mirror of https://github.com/AxioDL/tinyxml2.git
merging handles to the master
This commit is contained in:
commit
8712757389
2
dox
2
dox
|
@ -32,7 +32,7 @@ PROJECT_NAME = "TinyXML-2"
|
||||||
# This could be handy for archiving the generated documentation or
|
# This could be handy for archiving the generated documentation or
|
||||||
# if some version control system is used.
|
# if some version control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = 0.9.3
|
PROJECT_NUMBER = 0.9.4
|
||||||
|
|
||||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||||
# for a project that appears at the top of each page and should give viewer
|
# for a project that appears at the top of each page and should give viewer
|
||||||
|
|
|
@ -11,8 +11,7 @@ github.com/leethomason/tinyxml2
|
||||||
The online HTML version of these docs:
|
The online HTML version of these docs:
|
||||||
http://grinninglizard.com/tinyxml2docs/index.html
|
http://grinninglizard.com/tinyxml2docs/index.html
|
||||||
|
|
||||||
Where examples are in the "related pages" tab:
|
Examples are in the "related pages" tab of the HTML docs.
|
||||||
http://grinninglizard.com/tinyxml2docs/pages.html
|
|
||||||
|
|
||||||
<h2> What it does. </h2>
|
<h2> What it does. </h2>
|
||||||
|
|
||||||
|
|
137
tinyxml2.h
137
tinyxml2.h
|
@ -97,7 +97,7 @@ distribution.
|
||||||
|
|
||||||
static const int TIXML2_MAJOR_VERSION = 0;
|
static const int TIXML2_MAJOR_VERSION = 0;
|
||||||
static const int TIXML2_MINOR_VERSION = 9;
|
static const int TIXML2_MINOR_VERSION = 9;
|
||||||
static const int TIXML2_PATCH_VERSION = 3;
|
static const int TIXML2_PATCH_VERSION = 4;
|
||||||
|
|
||||||
namespace tinyxml2
|
namespace tinyxml2
|
||||||
{
|
{
|
||||||
|
@ -407,7 +407,7 @@ public:
|
||||||
XML Document Object Model (DOM), except XMLAttributes.
|
XML Document Object Model (DOM), except XMLAttributes.
|
||||||
Nodes have siblings, a parent, and children which can
|
Nodes have siblings, a parent, and children which can
|
||||||
be navigated. A node is always in a XMLDocument.
|
be navigated. A node is always in a XMLDocument.
|
||||||
The type of a TiXmlNode can be queried, and it can
|
The type of a XMLNode can be queried, and it can
|
||||||
be cast to its more defined type.
|
be cast to its more defined type.
|
||||||
|
|
||||||
An XMLDocument allocates memory for all its Nodes.
|
An XMLDocument allocates memory for all its Nodes.
|
||||||
|
@ -1132,6 +1132,139 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
A XMLHandle is a class that wraps a node pointer with null checks; this is
|
||||||
|
an incredibly useful thing. Note that XMLHandle is not part of the TinyXML
|
||||||
|
DOM structure. It is a separate utility class.
|
||||||
|
|
||||||
|
Take an example:
|
||||||
|
@verbatim
|
||||||
|
<Document>
|
||||||
|
<Element attributeA = "valueA">
|
||||||
|
<Child attributeB = "value1" />
|
||||||
|
<Child attributeB = "value2" />
|
||||||
|
</Element>
|
||||||
|
<Document>
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very
|
||||||
|
easy to write a *lot* of code that looks like:
|
||||||
|
|
||||||
|
@verbatim
|
||||||
|
XMLElement* root = document.FirstChildElement( "Document" );
|
||||||
|
if ( root )
|
||||||
|
{
|
||||||
|
XMLElement* element = root->FirstChildElement( "Element" );
|
||||||
|
if ( element )
|
||||||
|
{
|
||||||
|
XMLElement* child = element->FirstChildElement( "Child" );
|
||||||
|
if ( child )
|
||||||
|
{
|
||||||
|
XMLElement* child2 = child->NextSiblingElement( "Child" );
|
||||||
|
if ( child2 )
|
||||||
|
{
|
||||||
|
// Finally do something useful.
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
And that doesn't even cover "else" cases. XMLHandle addresses the verbosity
|
||||||
|
of such code. A XMLHandle checks for null pointers so it is perfectly safe
|
||||||
|
and correct to use:
|
||||||
|
|
||||||
|
@verbatim
|
||||||
|
XMLHandle docHandle( &document );
|
||||||
|
XMLElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild().NextSibling().ToElement();
|
||||||
|
if ( child2 )
|
||||||
|
{
|
||||||
|
// do something useful
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
Which is MUCH more concise and useful.
|
||||||
|
|
||||||
|
It is also safe to copy handles - internally they are nothing more than node pointers.
|
||||||
|
@verbatim
|
||||||
|
XMLHandle handleCopy = handle;
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
See also XMLConstHandle, which is the same as XMLHandle, but operates on const objects.
|
||||||
|
*/
|
||||||
|
class XMLHandle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
|
||||||
|
XMLHandle( XMLNode* _node ) { node = _node; }
|
||||||
|
/// Create a handle from a node.
|
||||||
|
XMLHandle( XMLNode& _node ) { node = &_node; }
|
||||||
|
/// Copy constructor
|
||||||
|
XMLHandle( const XMLHandle& ref ) { node = ref.node; }
|
||||||
|
/// Assignment
|
||||||
|
XMLHandle operator=( const XMLHandle& ref ) { node = ref.node; return *this; }
|
||||||
|
|
||||||
|
/// Get the first child of this handle.
|
||||||
|
XMLHandle FirstChild() { return XMLHandle( node ? node->FirstChild() : 0 ); }
|
||||||
|
/// Get the first child element of this handle.
|
||||||
|
XMLHandle FirstChildElement( const char* value=0 ) { return XMLHandle( node ? node->FirstChildElement( value ) : 0 ); }
|
||||||
|
/// Get the last child of this handle.
|
||||||
|
XMLHandle LastChild() { return XMLHandle( node ? node->LastChild() : 0 ); }
|
||||||
|
/// Get the last child element of this handle.
|
||||||
|
XMLHandle LastChildElement( const char* _value=0 ) { return XMLHandle( node ? node->LastChildElement( _value ) : 0 ); }
|
||||||
|
/// Get the previous sibling of this handle.
|
||||||
|
XMLHandle PreviousSibling() { return XMLHandle( node ? node->PreviousSibling() : 0 ); }
|
||||||
|
/// Get the previous sibling element of this handle.
|
||||||
|
XMLHandle PreviousSiblingElement( const char* _value=0 ) { return XMLHandle( node ? node->PreviousSiblingElement( _value ) : 0 ); }
|
||||||
|
/// Get the next sibling of this handle.
|
||||||
|
XMLHandle NextSibling() { return XMLHandle( node ? node->NextSibling() : 0 ); }
|
||||||
|
/// Get the next sibling element of this handle.
|
||||||
|
XMLHandle NextSiblingElement( const char* _value=0 ) { return XMLHandle( node ? node->NextSiblingElement( _value ) : 0 ); }
|
||||||
|
|
||||||
|
/// Safe cast to XMLNode. This can return null.
|
||||||
|
XMLNode* ToNode() { return node; }
|
||||||
|
/// Safe cast to XMLElement. This can return null.
|
||||||
|
XMLElement* ToElement() { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
|
||||||
|
/// Safe cast to XMLText. This can return null.
|
||||||
|
XMLText* ToText() { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
|
||||||
|
/// Safe cast to XMLUnknown. This can return null.
|
||||||
|
XMLUnknown* ToUnknown() { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
|
||||||
|
/// Safe cast to XMLDeclaration. This can return null.
|
||||||
|
XMLDeclaration* ToDeclaration() { return ( ( node && node->ToDeclaration() ) ? node->ToDeclaration() : 0 ); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
XMLNode* node;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
A variant of the XMLHandle class for working with const XMLNodes and Documents. It is the
|
||||||
|
same in all regards, except for the 'const' qualifiers. See XMLHandle for API.
|
||||||
|
*/
|
||||||
|
class XMLConstHandle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
XMLConstHandle( const XMLNode* _node ) { node = _node; }
|
||||||
|
XMLConstHandle( const XMLNode& _node ) { node = &_node; }
|
||||||
|
XMLConstHandle( const XMLConstHandle& ref ) { node = ref.node; }
|
||||||
|
|
||||||
|
XMLConstHandle operator=( const XMLConstHandle& ref ) { node = ref.node; return *this; }
|
||||||
|
|
||||||
|
const XMLConstHandle FirstChild() const { return XMLConstHandle( node ? node->FirstChild() : 0 ); }
|
||||||
|
const XMLConstHandle FirstChildElement( const char* value=0 ) const { return XMLConstHandle( node ? node->FirstChildElement( value ) : 0 ); }
|
||||||
|
const XMLConstHandle LastChild() const { return XMLConstHandle( node ? node->LastChild() : 0 ); }
|
||||||
|
const XMLConstHandle LastChildElement( const char* _value=0 ) const { return XMLConstHandle( node ? node->LastChildElement( _value ) : 0 ); }
|
||||||
|
const XMLConstHandle PreviousSibling() const { return XMLConstHandle( node ? node->PreviousSibling() : 0 ); }
|
||||||
|
const XMLConstHandle PreviousSiblingElement( const char* _value=0 ) const { return XMLConstHandle( node ? node->PreviousSiblingElement( _value ) : 0 ); }
|
||||||
|
const XMLConstHandle NextSibling() const { return XMLConstHandle( node ? node->NextSibling() : 0 ); }
|
||||||
|
const XMLConstHandle NextSiblingElement( const char* _value=0 ) const { return XMLConstHandle( node ? node->NextSiblingElement( _value ) : 0 ); }
|
||||||
|
|
||||||
|
|
||||||
|
const XMLNode* ToNode() const { return node; }
|
||||||
|
const XMLElement* ToElement() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
|
||||||
|
const XMLText* ToText() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
|
||||||
|
const XMLUnknown* ToUnknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
|
||||||
|
const XMLDeclaration* ToDeclaration() const { return ( ( node && node->ToDeclaration() ) ? node->ToDeclaration() : 0 ); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
const XMLNode* node;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Printing functionality. The XMLPrinter gives you more
|
Printing functionality. The XMLPrinter gives you more
|
||||||
|
|
28
xmltest.cpp
28
xmltest.cpp
|
@ -761,6 +761,34 @@ int main( int /*argc*/, const char ** /*argv*/ )
|
||||||
XMLTest( "Error in snprinf handling.", true, doc.Error() );
|
XMLTest( "Error in snprinf handling.", true, doc.Error() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -------- Handles ------------
|
||||||
|
{
|
||||||
|
static const char* xml = "<element attrib='bar'><sub>Text</sub></element>";
|
||||||
|
XMLDocument doc;
|
||||||
|
doc.Parse( xml );
|
||||||
|
|
||||||
|
XMLElement* ele = XMLHandle( doc ).FirstChildElement( "element" ).FirstChild().ToElement();
|
||||||
|
XMLTest( "Handle, success, mutable", ele->Value(), "sub" );
|
||||||
|
|
||||||
|
XMLHandle docH( doc );
|
||||||
|
ele = docH.FirstChildElement( "none" ).FirstChildElement( "element" ).ToElement();
|
||||||
|
XMLTest( "Handle, dne, mutable", 0, (int)ele );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
static const char* xml = "<element attrib='bar'><sub>Text</sub></element>";
|
||||||
|
XMLDocument doc;
|
||||||
|
doc.Parse( xml );
|
||||||
|
XMLConstHandle docH( doc );
|
||||||
|
|
||||||
|
const XMLElement* ele = docH.FirstChildElement( "element" ).FirstChild().ToElement();
|
||||||
|
XMLTest( "Handle, success, const", ele->Value(), "sub" );
|
||||||
|
|
||||||
|
ele = docH.FirstChildElement( "none" ).FirstChildElement( "element" ).ToElement();
|
||||||
|
XMLTest( "Handle, dne, const", 0, (int)ele );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ----------- Performance tracking --------------
|
// ----------- Performance tracking --------------
|
||||||
{
|
{
|
||||||
#if defined( _MSC_VER )
|
#if defined( _MSC_VER )
|
||||||
|
|
Loading…
Reference in New Issue