221 lines
5.6 KiB
Plaintext
221 lines
5.6 KiB
Plaintext
/**
|
|
@page ticppTutorial TinyXML++ Tutorial
|
|
Take a look here @subpage ticpp
|
|
|
|
This is a work in progress.
|
|
|
|
|
|
@page ticpp TinyXML++
|
|
<h2> General Concepts </h2>
|
|
The TinyXML++ classes are all wrappers around the corresponding classes within TinyXML.
|
|
|
|
There is no reason to create TinyXML++ objects on the heap, using @p new, because the memory is managed for you. If you choose
|
|
to use @p new to create TinyXML++ objects, you will @b always need to use @p delete to clean up.
|
|
|
|
Basically, TinyXML++ objects are just wrappers around TinyXML pointers.
|
|
|
|
<h2> Goals </h2>
|
|
- Simplify the use and interface of TinyXml, using C++ concepts.
|
|
- Use exceptions for error handling, so there are no return codes to check
|
|
- Use templates for automatic type conversion
|
|
- Use STL style iterators to move through nodes and attributes
|
|
|
|
<h2> Details </h2>
|
|
<h3> Use exceptions for error handling </h3>
|
|
When using the original TinyXML, every function returns a value indicating
|
|
success or failure. A programmer would have to check that value to ensure
|
|
the function succeeded.
|
|
|
|
Example:
|
|
@code
|
|
// Load a document
|
|
TiXmlDocument doc( pFilename );
|
|
if ( !doc.LoadFile() ) return;
|
|
|
|
// Get a node
|
|
TiXmlElement* pElem = doc.FirstChildElement();
|
|
if ( !pElem ) return;
|
|
|
|
// Get the node we want
|
|
pElem = pElem->NextSibling();
|
|
if ( !pElem ) return;
|
|
|
|
// do something useful here
|
|
@endcode
|
|
|
|
An alternative was to use TiXmlHandle, which allows for function chaining by
|
|
checking the intermediate function return values:
|
|
|
|
Example:
|
|
@code
|
|
// Load a document
|
|
TiXmlDocument doc(pFilename);
|
|
if (!doc.LoadFile()) return;
|
|
|
|
// Make a document handle
|
|
TiXmlHandle hDoc(&doc);
|
|
|
|
// Get an element by using the handle to chain calls
|
|
// Note the conversion of the TiXmlHandle to the TiXmlElement* - .Element()
|
|
TiXmlElement* pElem = hDoc.FirstChildElement().NextSibling().Element();
|
|
if ( !pElem ) return;
|
|
|
|
// do something useful here
|
|
@endcode
|
|
|
|
With TinyXML++, if there is an error during a function call, it throws an exception.
|
|
This means that a programmer can assume that every function is successful, as
|
|
long as the functions are enclosed in a try-catch block.
|
|
|
|
Example:
|
|
@code
|
|
try
|
|
{
|
|
// Load a document
|
|
ticpp::Document doc( pFilename );
|
|
doc.LoadFile();
|
|
|
|
// Get an element by chaining calls - no return values to check, no TiXmlHandle
|
|
ticpp::Element* pElem = doc.FirstChildElement()->NextSibling();
|
|
|
|
// do something useful here
|
|
}
|
|
catch( ticpp::Exception& ex )
|
|
{
|
|
// If any function has an error, execution will enter here.
|
|
// Report the error
|
|
std::cout << ex.what();
|
|
}
|
|
@endcode
|
|
|
|
|
|
<h3> Use templates for automatic type conversion </h3>
|
|
When using TinyXML, a programmer either needs to convert values to and from
|
|
strings, or choose from one of many overloads to get the value in the desired
|
|
type.
|
|
|
|
Example:
|
|
@code
|
|
// Load a document
|
|
TiXmlDocument doc( pFilename );
|
|
if ( !doc.LoadFile() ) return;
|
|
|
|
// Get a node
|
|
TiXmlElement* pElem = doc.FirstChildElement();
|
|
if ( !pElem ) return;
|
|
|
|
// Get the node we want
|
|
pElem = pElem->NextSibling();
|
|
if ( !pElem ) return;
|
|
|
|
// Get the attribute as a string, convert to int
|
|
const char* pszAttr = pElem->Attribute( "myAttribute" );
|
|
int attr = atoi( pszAttr );
|
|
|
|
// Get the attribute as an int
|
|
int attr2;
|
|
if ( TIXML_SUCCESS != pElem->QueryIntAttribute( "myAttribute", &attr2 ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Get the attribute as a double
|
|
double attr3;
|
|
if ( TIXML_SUCCESS != pElem->QueryDoubleAttribute( "myAttribute", &attr3 ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Get the attribute as a float
|
|
float attr4;
|
|
if ( TIXML_SUCCESS != pElem->QueryFloatAttribute( "myAttribute", &attr4 ) )
|
|
{
|
|
return;
|
|
}
|
|
@endcode
|
|
|
|
TinyXML++ uses templates for automatic type conversion.
|
|
|
|
Example:
|
|
@code
|
|
try
|
|
{
|
|
// Load a document
|
|
ticpp::Document doc( pFilename );
|
|
doc.LoadFile();
|
|
|
|
// Get an element by chaining calls - no return values to check, no TiXmlHandle
|
|
ticpp::Element* pElem = doc.FirstChildElement()->NextSibling();
|
|
|
|
// GetAttribute can determine the type of the pointer, and convert automatically
|
|
|
|
// Get the attribute as a string
|
|
std::string attr;
|
|
pElem->GetAttribute( "myAttribute", &attr );
|
|
|
|
// Get the attribute as an int
|
|
int attr2;
|
|
pElem->GetAttribute( "myAttribute", &attr2 );
|
|
|
|
// Get the attribute as an float
|
|
float attr3;
|
|
pElem->GetAttribute( "myAttribute", &attr3 );
|
|
|
|
// Get the attribute as an double
|
|
double attr4;
|
|
pElem->GetAttribute( "myAttribute", &attr4 );
|
|
|
|
// Get the attribute as an bool
|
|
bool attr5;
|
|
pElem->GetAttribute( "myAttribute", &attr5 );
|
|
|
|
}
|
|
catch( ticpp::Exception& ex )
|
|
{
|
|
// If any function has an error, execution will enter here.
|
|
// Report the error
|
|
std::cout << ex.what();
|
|
}
|
|
@endcode
|
|
<h3> Use STL style iterators to move through nodes and attributes </h3>
|
|
TinyXML has two ways to iterate:
|
|
|
|
First Method:
|
|
@code
|
|
for( child = parent->FirstChild( false ); child; child = child->NextSibling( false ) )
|
|
@endcode
|
|
|
|
Second Method:
|
|
@code
|
|
child = 0;
|
|
while( child = parent->IterateChildren( child ) )
|
|
@endcode
|
|
|
|
Although both methods work quite well, the syntax is not familiar.
|
|
TinyXML++ introduces iterators:
|
|
@code
|
|
ticpp::Iterator< ticpp::Node > child;
|
|
for ( child = child.begin( parent ); child != child.end(); child++ )
|
|
@endcode
|
|
|
|
Iterators have the added advantage of filtering by type:
|
|
@code
|
|
// Only iterates through Comment nodes
|
|
ticpp::Iterator< ticpp::Comment > child;
|
|
for ( child = child.begin( parent ); child != child.end(); child++ )
|
|
@endcode
|
|
|
|
@code
|
|
// Only iterates through Element nodes with value "ElementValue"
|
|
ticpp::Iterator< ticpp::Element > child( "ElementValue" );
|
|
for ( child = child.begin( parent ); child != child.end(); child++ )
|
|
@endcode
|
|
|
|
Finally, Iterators also work with Attributes
|
|
@code
|
|
ticpp::Iterator< ticpp::Attribute > attribute;
|
|
for ( attribute = attribute.begin( element ); attribute != attribute.end(); attribute++ )
|
|
@endcode
|
|
|
|
*/
|