/**
@page ticppTutorial TinyXML++ Tutorial
Take a look here @subpage ticpp
This is a work in progress.
@page ticpp TinyXML++
General Concepts
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.
Goals
- 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
Details
Use exceptions for error handling
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.m_details;
}
@endcode
Use templates for automatic type conversion
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.m_details;
}
@endcode
Use STL style iterators to move through nodes and attributes
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 = parent->FirstChild(); child != child.end(); child++ )
@endcode
Iterators have the added advantage of filtering by type:
@code
// Only iterates through Element nodes
ticpp::Iterator< ticpp::Element > child;
for ( child = parent->FirstChild(); child != child.end(); child++ )
@endcode
@code
// Only iterates through Comment nodes
ticpp::Iterator< ticpp::Comment > child;
for ( child = parent->FirstChild(); child != child.end(); child++ )
@endcode
Finally, Iterators also work with Attributes
@code
ticpp::Iterator< ticpp::Attribute > attribute;
for ( attribute = element->FirstAttribute(); attribute != attribute.end(); attribute++ )
@endcode
*/