Main Page | Class Hierarchy | Class List | File List | Class Members

TinyXML Tutorial

Tutorial Preliminary

These pages contains a bunch of examples of using TinyXml.

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.

So if the example has a function:

	void write_simple_doc()
	{
		...
	}
	

then the *complete* program you need to try it is:

	#include "stdafx.h" // <-- you MIGHT need this
	#include "tinyxml.h" // <-- you definitely need this ;)

	void write_simple_doc()
	{
		...
	}

	void main( void )
	{
		write_simple_doc();
	}
	

Two example XML datasets/files will be used. The first looks like this:

	<?xml version="1.0" ?>
	<Hello>World</Hello>
	

The other:

	<?xml version="1.0" ?>
	<poetry>
		<verse>
			Alas
			  Great Whatever
				Alas (again)
		</verse>
	</poetry>
	

Getting Started

Load XML from a file

Loading a file is as simple as:

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

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:

	<?xml version="1.0" ?>
	<Hello>World</Hello>
	

You'll see this:

	DOCUMENT
	+ DECLARATION
	+ ELEMENT Hello
	  + TEXT[World]
	

Building Documents Programatically

Example:

	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" );
	}
	

Alternatively:

	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" );
	}
	

Both of these produce the same XML, namely:

	<?xml version="1.0" ?>
	<Hello>World</Hello>
	

Or in structure form:

	DOCUMENT
	+ DECLARATION
	+ ELEMENT Hello
	  + TEXT[World]
	

Saving Documents to File

This function:

	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" );  
	}  
	

Produces this structure:

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

The file ``madeByHand3.xml`` looks exactly like this (including indents):

	<?xml version="1.0" ?>
	<Hello>Opening a new salutation
	    <Greeting>How are you?
	        <Language>English</Language>
	    </Greeting>
	    <Exclamation>You have children!</Exclamation>
	</Hello>
	

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.

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.

[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.]

Iterating Over Documents

Dump structure of a Document to STDOUT

Often when you're starting its helpful and reassuring to know that you're document got loaded as you expect it to.

Below I've defined a function to walk a document and write contents to STDOUT:

	// 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 );
		}
	}
	

To load a file and dump its structure:

	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" );
		}
	}
	

If you run this with the first XML file you'll see this on STDOUT:

	DOCUMENT
	+ DECLARATION
	+ ELEMENT Hello
	  + TEXT[World]
	

and on the second XML file:

	DOCUMENT
	+ DECLARATION
	+ ELEMENT poetry
	  + COMMENT:  my great work of art
	  + ELEMENT verse
	    + TEXT[
	Alas
	  Great Whatever
	    Alas (again)
	]
	

Note that if you call dump_to_stdout like this:

	dump_to_stdout( doc.RootElement());
	

You'll see this instead:

	ELEMENT Hello
	+ TEXT[World]
	

and:

	ELEMENT poetry
	+ COMMENT:  my great work of art
	+ ELEMENT verse
  	+ TEXT[
	Alas
	  Great Whatever
	    Alas (again)
	] 
	

Authors and Changes


Generated on Sat Oct 8 14:15:30 2005 for TinyXml by  doxygen 1.4.4