You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
323 lines
9.9 KiB
323 lines
9.9 KiB
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
|
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"> |
|
<title>TinyXml: TinyXML Tutorial</title> |
|
<link href="doxygen.css" rel="stylesheet" type="text/css"> |
|
</head><body> |
|
<!-- Generated by Doxygen 1.4.4 --> |
|
<div class="qindex"><a class="qindex" href="index.html">Main Page</a> | <a class="qindex" href="hierarchy.html">Class Hierarchy</a> | <a class="qindex" href="annotated.html">Class List</a> | <a class="qindex" href="files.html">File List</a> | <a class="qindex" href="functions.html">Class Members</a></div> |
|
<div class="nav"> |
|
<a class="el" href="index.html">index</a></div> |
|
<h1><a class="anchor" name="tutorial0">TinyXML Tutorial</a></h1><h1>Tutorial Preliminary </h1> |
|
<p> |
|
These pages contains a bunch of examples of using TinyXml.<p> |
|
Each demo is written in a standalone function. If you want to try the code, all you need to do is copy/paste the code into a file, then have a main to call it.<p> |
|
So if the example has a function:<p> |
|
<div class="fragment"><pre class="fragment"> void write_simple_doc() |
|
{ |
|
... |
|
} |
|
</pre></div><p> |
|
then the *complete* program you need to try it is:<p> |
|
<div class="fragment"><pre class="fragment"> #include "stdafx.h" // <-- you MIGHT need this |
|
#include "tinyxml.h" // <-- you definitely need this ;) |
|
|
|
void write_simple_doc() |
|
{ |
|
... |
|
} |
|
|
|
void main( void ) |
|
{ |
|
write_simple_doc(); |
|
} |
|
</pre></div><p> |
|
Two example XML datasets/files will be used. The first looks like this:<p> |
|
<div class="fragment"><pre class="fragment"> <?xml version="1.0" ?> |
|
<Hello>World</Hello> |
|
</pre></div><p> |
|
The other:<p> |
|
<div class="fragment"><pre class="fragment"> <?xml version="1.0" ?> |
|
<poetry> |
|
<verse> |
|
Alas |
|
Great Whatever |
|
Alas (again) |
|
</verse> |
|
</poetry> |
|
</pre></div><p> |
|
<h1>Getting Started </h1> |
|
<p> |
|
<h2>Load XML from a file </h2> |
|
<p> |
|
Loading a file is as simple as:<p> |
|
<div class="fragment"><pre class="fragment"> void load_file( ) |
|
{ |
|
TiXmlDocument doc( "demo.xml" ); |
|
bool loadOkay = doc.LoadFile(); |
|
|
|
if ( loadOkay ) |
|
{ |
|
// Your document is loaded - do what you like |
|
// with it. |
|
// |
|
// Here we'll dump the structure to STDOUT, |
|
// just for example |
|
dump_to_stdout( &doc ); |
|
} |
|
else |
|
{ |
|
// load failed |
|
} |
|
} |
|
</pre></div><p> |
|
The ``dump_to_stdout`` function is defined in the section `Dump structure of a Document to STDOUT` below. If you run this program with this XML:<p> |
|
<div class="fragment"><pre class="fragment"> <?xml version="1.0" ?> |
|
<Hello>World</Hello> |
|
</pre></div><p> |
|
You'll see this:<p> |
|
<div class="fragment"><pre class="fragment"> DOCUMENT |
|
+ DECLARATION |
|
+ ELEMENT Hello |
|
+ TEXT[World] |
|
</pre></div><p> |
|
<h2>Building Documents Programatically </h2> |
|
<p> |
|
Example:<p> |
|
<div class="fragment"><pre class="fragment"> void write_simple_doc( ) |
|
{ |
|
// Make 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 ); |
|
|
|
dump_to_stdout( &doc ); |
|
doc.SaveFile( "madeByHand.xml" ); |
|
} |
|
</pre></div><p> |
|
Alternatively:<p> |
|
<div class="fragment"><pre class="fragment"> void write_simple_doc2( ) |
|
{ |
|
// same as write_simple_doc1 but add each node |
|
// as early as possible into the tree. |
|
|
|
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 ); |
|
|
|
dump_to_stdout( &doc ); |
|
doc.SaveFile( "madeByHand2.xml" ); |
|
} |
|
</pre></div><p> |
|
Both of these produce the same XML, namely:<p> |
|
<div class="fragment"><pre class="fragment"> <?xml version="1.0" ?> |
|
<Hello>World</Hello> |
|
</pre></div><p> |
|
Or in structure form:<p> |
|
<div class="fragment"><pre class="fragment"> DOCUMENT |
|
+ DECLARATION |
|
+ ELEMENT Hello |
|
+ TEXT[World] |
|
</pre></div><p> |
|
<h2>Saving Documents to File </h2> |
|
<p> |
|
This function:<p> |
|
<div class="fragment"><pre class="fragment"> void write_simple_doc3( ) |
|
{ |
|
// This example courtesy of polocolege |
|
|
|
TiXmlDocument doc; |
|
TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "", "" ); |
|
doc.LinkEndChild( decl ); |
|
|
|
TiXmlElement * element = new TiXmlElement( "Hello" ); |
|
doc.LinkEndChild( element ); |
|
|
|
TiXmlText * text = new TiXmlText( "Opening a new salutation" ); |
|
element->LinkEndChild( text ); |
|
|
|
TiXmlElement * element2 = new TiXmlElement( "Greeting" ); |
|
element->LinkEndChild( element2 ); |
|
|
|
TiXmlText * text2 = new TiXmlText( "How are you?" ); |
|
element2->LinkEndChild( text2 ); |
|
|
|
TiXmlElement * element3 = new TiXmlElement( "Language" ); |
|
element2->LinkEndChild( element3 ); |
|
|
|
TiXmlText * text3 = new TiXmlText( "English" ); |
|
element3->LinkEndChild( text3 ); |
|
|
|
TiXmlElement * element4 = new TiXmlElement( "Exclamation" ); |
|
element->LinkEndChild( element4 ); |
|
|
|
TiXmlText * text4 = new TiXmlText( "You have children!" ); |
|
element4->LinkEndChild( text4 ); |
|
|
|
dump_to_stdout( &doc ); |
|
doc.SaveFile( "madeByHand3.xml" ); |
|
} |
|
</pre></div><p> |
|
Produces this structure:<p> |
|
<div class="fragment"><pre class="fragment"> Document |
|
+ Declaration |
|
+ Element "Hello" |
|
+ Text: [Opening a new salutation] |
|
+ Element "Greeting" |
|
+ Text: [How are you?] |
|
+ Element "Language" |
|
+ Text: [English] |
|
+ Element "Exclamation" |
|
+ Text: [You have children!] |
|
</pre></div><p> |
|
The file ``madeByHand3.xml`` looks exactly like this (including indents):<p> |
|
<div class="fragment"><pre class="fragment"> <?xml version="1.0" ?> |
|
<Hello>Opening a new salutation |
|
<Greeting>How are you? |
|
<Language>English</Language> |
|
</Greeting> |
|
<Exclamation>You have children!</Exclamation> |
|
</Hello> |
|
</pre></div><p> |
|
I was surprised that TinyXml, by default, writes the XML in what other APIs call a "pretty" format - it modifies the whitespace of text of elements that contain other nodes so that writing the tree includes an indication of nesting level.<p> |
|
I haven't looked yet to see if there is a way to turn off indenting when writing a file - its bound to be easy.<p> |
|
[Lee: It's easy in STL mode, just use cout << myDoc. Non-STL mode is always in "pretty" format. Adding a switch would be a nice feature and has been requested.]<p> |
|
<h1>Iterating Over Documents </h1> |
|
<p> |
|
<h2>Dump structure of a Document to STDOUT </h2> |
|
<p> |
|
Often when you're starting its helpful and reassuring to know that you're document got loaded as you expect it to.<p> |
|
Below I've defined a function to walk a document and write contents to STDOUT:<p> |
|
<div class="fragment"><pre class="fragment"> // a utility function defining a very simple method to indent a line of text |
|
const char * getIndent( unsigned int numIndents ) |
|
{ |
|
static const char * pINDENT = " + "; |
|
static const unsigned int LENGTH = strlen( pINDENT ); |
|
|
|
if ( numIndents > LENGTH ) numIndents = LENGTH; |
|
|
|
return &pINDENT[ LENGTH-numIndents ]; |
|
} |
|
|
|
void dump_to_stdout( TiXmlNode * pParent, unsigned int indent = 0 ) |
|
{ |
|
if ( !pParent ) return; |
|
|
|
TiXmlText *pText; |
|
int t = pParent->Type(); |
|
printf( "%s", getIndent( indent)); |
|
|
|
switch ( t ) |
|
{ |
|
case TiXmlNode::DOCUMENT: |
|
printf( "Document" ); |
|
break; |
|
|
|
case TiXmlNode::ELEMENT: |
|
printf( "Element \"%s\"", pParent->Value() ); |
|
break; |
|
|
|
case TiXmlNode::COMMENT: |
|
printf( "Comment: \"%s\"", pParent->Value()); |
|
break; |
|
|
|
case TiXmlNode::UNKNOWN: |
|
printf( "Unknown" ); |
|
break; |
|
|
|
case TiXmlNode::TEXT: |
|
pText = pParent->ToText(); |
|
printf( "Text: [%s]", pText->Value() ); |
|
break; |
|
|
|
case TiXmlNode::DECLARATION: |
|
printf( "Declaration" ); |
|
break; |
|
default: |
|
break; |
|
} |
|
printf( "\n" ); |
|
|
|
TiXmlNode * pChild; |
|
|
|
for ( pChild = pParent->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) |
|
{ |
|
dump_to_stdout( pChild, indent+2 ); |
|
} |
|
} |
|
</pre></div><p> |
|
To load a file and dump its structure:<p> |
|
<div class="fragment"><pre class="fragment"> void load_and_display( ) |
|
{ |
|
// important for the poetry demo, but you may not need this |
|
// in your own projects |
|
TiXmlBase::SetCondenseWhiteSpace( false ); |
|
|
|
TiXmlDocument doc( "demo.xml" ); |
|
bool loadOkay = doc.LoadFile(); |
|
|
|
if ( loadOkay ) |
|
{ |
|
dump_to_stdout( &doc ); |
|
} |
|
else |
|
{ |
|
printf( "Something went wrong\n" ); |
|
} |
|
} |
|
</pre></div><p> |
|
If you run this with the first XML file you'll see this on STDOUT:<p> |
|
<div class="fragment"><pre class="fragment"> DOCUMENT |
|
+ DECLARATION |
|
+ ELEMENT Hello |
|
+ TEXT[World] |
|
</pre></div><p> |
|
and on the second XML file:<p> |
|
<div class="fragment"><pre class="fragment"> DOCUMENT |
|
+ DECLARATION |
|
+ ELEMENT poetry |
|
+ COMMENT: my great work of art |
|
+ ELEMENT verse |
|
+ TEXT[ |
|
Alas |
|
Great Whatever |
|
Alas (again) |
|
] |
|
</pre></div><p> |
|
Note that if you call dump_to_stdout like this:<p> |
|
<div class="fragment"><pre class="fragment"> dump_to_stdout( doc.RootElement()); |
|
</pre></div><p> |
|
You'll see this instead:<p> |
|
<div class="fragment"><pre class="fragment"> ELEMENT Hello |
|
+ TEXT[World] |
|
</pre></div><p> |
|
and:<p> |
|
<div class="fragment"><pre class="fragment"> ELEMENT poetry |
|
+ COMMENT: my great work of art |
|
+ ELEMENT verse |
|
+ TEXT[ |
|
Alas |
|
Great Whatever |
|
Alas (again) |
|
] |
|
</pre></div><p> |
|
<em> Authors and Changes <ul> |
|
<li> |
|
Written by Ellers, April 2005 </li> |
|
<li> |
|
Minor edits and integration into doc system, Lee Thomason September 2005 </li> |
|
</ul> |
|
</em> <hr size="1"><address style="align: right;"><small>Generated on Sat Oct 8 14:15:30 2005 for TinyXml by |
|
<a href="http://www.doxygen.org/index.html"> |
|
<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.4 </small></address> |
|
</body> |
|
</html>
|
|
|