Import the TinyXML dependency into the repository
This commit is contained in:
220
osx/dialogxml/xml-parser/tutorial_ticpp.txt
Normal file
220
osx/dialogxml/xml-parser/tutorial_ticpp.txt
Normal file
@@ -0,0 +1,220 @@
|
||||
/**
|
||||
@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
|
||||
|
||||
*/
|
Reference in New Issue
Block a user