| Author: | Andrew Ellerton |
|---|---|
| Date: | April 2004 |
This page 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>
<!-- my great work of art -->
<verse>
<?xml version="1.0" ?>
<poetry>
<!-- my great work of art -->
<verse>
Alas
Great Whatever
Alas (again)
</verse>
</poetry>
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]
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]
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.
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)
]
More to come later :)