<!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>