您的位置:首页 > 其它

TinyXML 指南 二

2009-05-27 17:53 295 查看
开始

把文件加载成XML

把一个文件加载成TinyXML DOM的最简单方法是:

TiXmlDocument doc( "demo.xml"
);

doc.LoadFile();
一个更接近于现实应用的例子如下。它加载文件并把内容显示到标准输出STDOUT上:

// 加载指定的文件并把它的结构输出到STDOUT上

void
dump_to_stdout(const char
* pFilename)

{

TiXmlDocument doc(pFilename);

bool
loadOkay = doc.LoadFile();

if
(loadOkay)

{

printf("/n%s:/n"
, pFilename);

dump_to_stdout( &doc ); // 稍后在指南中定义

}

else

{

printf("Failed to load file /"
%s/”/n", pFilename);

}

}
在main中使用此函数的一个简单应用示范如下:

int
main(void
)

{

dump_to_stdout("example1.xml"
);

return
0;

}
回想example1的XML:

<?xml version="1.0" ?>

<Hello>World</Hello>
用这个XML运行程序就会在控制台/DOS窗口中显示:

DOCUMENT

+ DECLARATION

+ ELEMENT Hello

+ TEXT[World]
”dump_to_stdout“函数稍后会在这份指南中定义,如果你想要理解怎样递归遍历一个DOM它会很有用。

用程序建立文档对象

这是用程序建立example1的方法:

void
build_simple_doc( )

{

// 生成xml: <?xml ..><Hello>World</Hello>

TiXmlDocument doc;

TiXmlDeclaration * decl = new
TiXmlDeclaration( "1.0"
, ""
, ""
);

TiXmlElement * element = new
TiXmlElement( "Hello"
);

TiXmlText * text = new
TiXmlText( "World"
);

element->LinkEndChild( text );

doc.LinkEndChild( decl );

doc.LinkEndChild( element );

doc.SaveFile( "madeByHand.xml"
);

}
然后可以用以下方法加载并显示在控制台上:

dump_to_stdout("madeByHand.xml"
); // 此函数稍后会中指南中定义

你会看到跟example1一模一样:

madeByHand.xml:

Document

+ Declaration

+ Element [Hello]

+ Text: [World]
这段代码会产生相同的XML DOM,但它以不同的顺序来创建和链接结点:

void
write_simple_doc2( )

{

// 实现与 write_simple_doc1一样的功能,(译注:我想它指是build_simple_doc
)

// 但尽可能早地把结点添加到树中。

TiXmlDocument doc;

TiXmlDeclaration * decl = new
TiXmlDeclaration( "1.0"
, ""
, ""
);

doc.LinkEndChild( decl );

TiXmlElement * element = new
TiXmlElement( "Hello"
);

doc.LinkEndChild( element );

TiXmlText * text = new
TiXmlText( "World"
);

element->LinkEndChild( text );

doc.SaveFile( "madeByHand2.xml"
);

}
两个都产生同样的XML,即:

<?xml version="1.0" ?>

<Hello>World</Hello>
结构构成都是:

DOCUMENT

+ DECLARATION

+ ELEMENT Hello

+ TEXT[World]
属性

给定一个存在的结点,设置它的属性是很容易的:

window = new
TiXmlElement( "Demo"
);

window->SetAttribute("name"
, "Circle"
);

window->SetAttribute("x"
, 5);

window->SetAttribute("y"
, 15);

window->SetDoubleAttribute("radius"
, 3.14159);
你也可以用TiXmlAttribute对象达到同样的目的。

下面的代码向我们展示了一种(并不只有一种)获取某一元素属性并打印出它们的名字和字符串值的方法,如果值能够被转化为整型数或者浮点数,也把值打印出来:

// 打印pElement的所有属性。

// 返回已打印的属性数量。

int
dump_attribs_to_stdout(TiXmlElement* pElement, unsigned
int
indent)

{

if
( !pElement ) return
0;

TiXmlAttribute* pAttrib=pElement->FirstAttribute();

int
i=0;

int
ival;

double
dval;

const char
* pIndent=getIndent(indent);

printf("/n"
);

while
(pAttrib)

{

printf( "%s%s: value=[%s]"
, pIndent, pAttrib->Name(), pAttrib->Value());

if
(pAttrib->QueryIntValue(&ival)==TIXML_SUCCESS) printf( " int=%d"
, ival);

if
(pAttrib->QueryDoubleValue(&dval)==TIXML_SUCCESS) printf( " d=%1.1f"
, dval);

printf( "/n"
);

i++;

pAttrib=pAttrib->Next();

}

return
i;

}
把文档对象写到文件中

把一个已经建立好的DOM写到文件中是非常简单的:

doc.SaveFile( saveFilename );
回想一下,比如example4:

<?xml version="1.0" ?>

<MyApp>

<!– Settings for MyApp –>

<Messages>

<Welcome>Welcome to MyApp</Welcome>

<Farewell>Thank you for using MyApp</Farewell>

</Messages>

<Windows>

<Window name="MainFrame" x="5" y="15" w="400" h="250" />

</Windows>

<Connection ip="192.168.0.1" timeout="123.456000" />

</MyApp>
以下函数建立这个DOM并把它写到“appsettings.xml”文件中:

void
write_app_settings_doc( )

{

TiXmlDocument doc;

TiXmlElement* msg;

TiXmlDeclaration* decl = new
TiXmlDeclaration( "1.0"
, ""
, ""
);

doc.LinkEndChild( decl );

TiXmlElement * root = new
TiXmlElement( "MyApp"
);

doc.LinkEndChild( root );

TiXmlComment * comment = new
TiXmlComment();

comment->SetValue(" Settings for MyApp "
);

root->LinkEndChild( comment );

TiXmlElement * msgs = new
TiXmlElement( "Messages"
);

root->LinkEndChild( msgs );

msg = new
TiXmlElement( "Welcome"
);

msg->LinkEndChild( new
TiXmlText( "Welcome to MyApp"
));

msgs->LinkEndChild( msg );

msg = new
TiXmlElement( "Farewell"
);

msg->LinkEndChild( new
TiXmlText( "Thank you for using MyApp"
));

msgs->LinkEndChild( msg );

TiXmlElement * windows = new
TiXmlElement( "Windows"
);

root->LinkEndChild( windows );

TiXmlElement * window;

window = new
TiXmlElement( "Window"
);

windows->LinkEndChild( window );

window->SetAttribute("name"
, "MainFrame"
);

window->SetAttribute("x"
, 5);

window->SetAttribute("y"
, 15);

window->SetAttribute("w"
, 400);

window->SetAttribute("h"
, 250);

TiXmlElement * cxn = new
TiXmlElement( "Connection"
);

root->LinkEndChild( cxn );

cxn->SetAttribute("ip"
, "192.168.0.1"
);

cxn->SetDoubleAttribute("timeout"
, 123.456); // 浮点数属性

dump_to_stdout( &doc );

doc.SaveFile( "appsettings.xml"
);

}
dump_to_stdout函数将显示如下结构:

Document

+ Declaration

+ Element [MyApp]

(No attributes)

+ Comment: [ Settings for MyApp ]

+ Element [Messages]

(No attributes)

+ Element [Welcome]

(No attributes)

+ Text: [Welcome to MyApp]

+ Element [Farewell]

(No attributes)

+ Text: [Thank you for using MyApp]

+ Element [Windows]

(No attributes)

+ Element [Window]

+ name: value=[MainFrame]

+ x: value=[5] int=5 d=5.0

+ y: value=[15] int=15 d=15.0

+ w: value=[400] int=400 d=400.0

+ h: value=[250] int=250 d=250.0

5 attributes

+ Element [Connection]

+ ip: value=[192.168.0.1] int=192 d=192.2

+ timeout: value=[123.456000] int=123 d=123.5

2 attributes
TinyXML默认以其它APIs称作“pretty”格式的方式来输出XML,对此我感到惊讶。这种格式修改了元素的文本结点中的空格,以使输出来的结点树包含一个嵌套层标记。

我还没有仔细看当写到一个文件中时是否有办法关闭这种缩进——这肯定很容易做到。(译注:这两句话大概是Ellers说的


[Lee:在STL模式下这很容易做到,只需要cout << myDoc就行了。在非STL模式下就总是用“pretty”格式了,加多一个开关是一个很好的特性,这已经被要求过了。]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: