From 3a68262c67a55f5dddef19b7b03ec303d080b77b Mon Sep 17 00:00:00 2001 From: Lee Thomason Date: Sun, 25 Mar 2012 13:19:40 -0700 Subject: [PATCH 1/7] minor doc fix --- tinyxml2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tinyxml2.h b/tinyxml2.h index 3382472..df5e891 100644 --- a/tinyxml2.h +++ b/tinyxml2.h @@ -405,7 +405,7 @@ public: XML Document Object Model (DOM), except XMLAttributes. Nodes have siblings, a parent, and children which can 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. An XMLDocument allocates memory for all its Nodes. From 3ffdd39dbf44c8a9dc40bbc74cebd747a8d93c94 Mon Sep 17 00:00:00 2001 From: Lee Thomason Date: Wed, 28 Mar 2012 17:27:55 -0700 Subject: [PATCH 2/7] handles wip --- tinyxml2.h | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/tinyxml2.h b/tinyxml2.h index 250ce79..7f6e611 100644 --- a/tinyxml2.h +++ b/tinyxml2.h @@ -1130,6 +1130,111 @@ 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 + + + + + + + @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 + TiXmlElement* root = document.FirstChildElement( "Document" ); + if ( root ) + { + TiXmlElement* element = root->FirstChildElement( "Element" ); + if ( element ) + { + TiXmlElement* child = element->FirstChildElement( "Child" ); + if ( child ) + { + TiXmlElement* child2 = child->NextSiblingElement( "Child" ); + if ( child2 ) + { + // Finally do something useful. + @endverbatim + + And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity + of such code. A TiXmlHandle checks for null pointers so it is perfectly safe + and correct to use: + + @verbatim + TiXmlHandle docHandle( &document ); + TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).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 + TiXmlHandle handleCopy = handle; + @endverbatim +*/ +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; } + XMLHandle( const XMLNode* _node ) { node = const_cast(_node); } + //XMLHandle( XMLNode& _node ) { node = &_node; } + XMLHandle( const XMLNode& _node ) { node = const_cast(&_node); } + XMLHandle( const XMLHandle& ref ) { node = ref.node; } + + XMLHandle operator=( XMLHandle ref ) { node = ref.node; return *this; } + + XMLHandle FirstChild() { return XMLHandle( node ? node->FirstChild() : static_cast(0) ); } + const XMLHandle FirstChild() const { return XMLHandle( node ? node->FirstChild() : 0 ); } + + XMLHandle FirstChildElement( const char* value=0 ) { return XMLHandle( node ? node->FirstChildElement( value ) : 0 ); } + const XMLHandle FirstChildElement( const char* value=0 ) const { return XMLHandle( node ? node->FirstChildElement( value ) : 0 ); } + + XMLHandle LastChild() { return XMLHandle( node ? node->LastChild() : 0 ); } + const XMLHandle LastChild() const { return XMLHandle( node ? node->LastChild() : 0 ); } + + XMLHandle LastChildElement( const char* _value=0 ) { return XMLHandle( node ? node->LastChildElement() : 0 ); } + const XMLHandle LastChildElement( const char* _value=0 ) const { return XMLHandle( node ? node->LastChildElement() : 0 ); } + + XMLHandle PreviousSibling() { return XMLHandle( node ? node->PreviousSibling() : 0 ); } + const XMLHandle PreviousSibling() const { return XMLHandle( node ? node->PreviousSibling() : 0 ); } + + XMLHandle PreviousSiblingElement( const char* _value=0 ) { return XMLHandle( node ? node->PreviousSiblingElement() : 0 ); } + const XMLHandle PreviousSiblingElement( const char* _value=0 ) const { return XMLHandle( node ? node->PreviousSiblingElement() : 0 ); } + + XMLHandle NextSibling() { return XMLHandle( node ? node->NextSibling() : 0 ); } + const XMLHandle NextSibling() const { return XMLHandle( node ? node->NextSibling() : 0 ); } + + XMLHandle NextSiblingElement( const char* _value=0 ) { return XMLHandle( node ? node->NextSiblingElement( _value ) : 0 ); } + const XMLHandle NextSiblingElement( const char* _value=0 ) const { return XMLHandle( node ? node->NextSiblingElement( _value ) : 0 ); } + + + XMLNode* ToNode() { return node; } + const XMLNode* ToNode() const { return node; } + XMLElement* ToElement() { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } + const XMLElement* ToElement() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } + XMLText* ToText() { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); } + const XMLText* ToText() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); } + XMLUnknown* ToUnknown() { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); } + const XMLUnknown* ToUnknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); } + XMLDeclaration* ToDeclaration() { return ( ( node && node->ToDeclaration() ) ? node->ToDeclaration() : 0 ); } + const XMLDeclaration* ToDeclaration() const { return ( ( node && node->ToDeclaration() ) ? node->ToDeclaration() : 0 ); } + +private: + XMLNode* node; +}; + /** Printing functionality. The XMLPrinter gives you more From 5708f814a693d8730e16ac384b8f75b35b68237a Mon Sep 17 00:00:00 2001 From: Lee Thomason Date: Wed, 28 Mar 2012 17:46:41 -0700 Subject: [PATCH 3/7] handles wip. not happy with const behavior --- tinyxml2.h | 16 ++++++++-------- xmltest.cpp | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/tinyxml2.h b/tinyxml2.h index 7f6e611..b9cdbd7 100644 --- a/tinyxml2.h +++ b/tinyxml2.h @@ -1187,10 +1187,10 @@ 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; } - XMLHandle( const XMLNode* _node ) { node = const_cast(_node); } - //XMLHandle( XMLNode& _node ) { node = &_node; } - XMLHandle( const XMLNode& _node ) { node = const_cast(&_node); } + XMLHandle( XMLNode* _node ) { node = _node; } + //XMLHandle( const XMLNode* _node ) { node = const_cast(_node); } + XMLHandle( XMLNode& _node ) { node = &_node; } + //XMLHandle( const XMLNode& _node ) { node = const_cast(&_node); } XMLHandle( const XMLHandle& ref ) { node = ref.node; } XMLHandle operator=( XMLHandle ref ) { node = ref.node; return *this; } @@ -1204,14 +1204,14 @@ public: XMLHandle LastChild() { return XMLHandle( node ? node->LastChild() : 0 ); } const XMLHandle LastChild() const { return XMLHandle( node ? node->LastChild() : 0 ); } - XMLHandle LastChildElement( const char* _value=0 ) { return XMLHandle( node ? node->LastChildElement() : 0 ); } - const XMLHandle LastChildElement( const char* _value=0 ) const { return XMLHandle( node ? node->LastChildElement() : 0 ); } + XMLHandle LastChildElement( const char* _value=0 ) { return XMLHandle( node ? node->LastChildElement( _value ) : 0 ); } + const XMLHandle LastChildElement( const char* _value=0 ) const { return XMLHandle( node ? node->LastChildElement( _value ) : 0 ); } XMLHandle PreviousSibling() { return XMLHandle( node ? node->PreviousSibling() : 0 ); } const XMLHandle PreviousSibling() const { return XMLHandle( node ? node->PreviousSibling() : 0 ); } - XMLHandle PreviousSiblingElement( const char* _value=0 ) { return XMLHandle( node ? node->PreviousSiblingElement() : 0 ); } - const XMLHandle PreviousSiblingElement( const char* _value=0 ) const { return XMLHandle( node ? node->PreviousSiblingElement() : 0 ); } + XMLHandle PreviousSiblingElement( const char* _value=0 ) { return XMLHandle( node ? node->PreviousSiblingElement( _value ) : 0 ); } + const XMLHandle PreviousSiblingElement( const char* _value=0 ) const { return XMLHandle( node ? node->PreviousSiblingElement( _value ) : 0 ); } XMLHandle NextSibling() { return XMLHandle( node ? node->NextSibling() : 0 ); } const XMLHandle NextSibling() const { return XMLHandle( node ? node->NextSibling() : 0 ); } diff --git a/xmltest.cpp b/xmltest.cpp index 20e3fa9..9ed4a5e 100644 --- a/xmltest.cpp +++ b/xmltest.cpp @@ -726,6 +726,22 @@ int main( int /*argc*/, const char ** /*argv*/ ) XMLTest( "Clone and Equal", 4, count ); } + // -------- Handles ------------ + { + static const char* xml = "Text"; + XMLDocument doc; + doc.Parse( xml ); + const XMLDocument& docC = doc; + + XMLElement* ele = XMLHandle( doc ).FirstChildElement( "element" ).FirstChild().ToElement(); + XMLTest( "Handle, success, mutable", ele->Value(), "sub" ); + + ele = XMLHandle( docC ).FirstChildElement( "element" ).FirstChild().ToElement(); + XMLTest( "Handle, success, mutable", ele->Value(), "sub" ); + + } + + // ----------- Performance tracking -------------- { #if defined( _MSC_VER ) From 00770d28553f4440696904196199a33b18048729 Mon Sep 17 00:00:00 2001 From: Lee Thomason Date: Wed, 28 Mar 2012 17:48:44 -0700 Subject: [PATCH 4/7] handles wip. not happy with const behavior --- xmltest.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xmltest.cpp b/xmltest.cpp index 9ed4a5e..07d593c 100644 --- a/xmltest.cpp +++ b/xmltest.cpp @@ -736,8 +736,8 @@ int main( int /*argc*/, const char ** /*argv*/ ) XMLElement* ele = XMLHandle( doc ).FirstChildElement( "element" ).FirstChild().ToElement(); XMLTest( "Handle, success, mutable", ele->Value(), "sub" ); - ele = XMLHandle( docC ).FirstChildElement( "element" ).FirstChild().ToElement(); - XMLTest( "Handle, success, mutable", ele->Value(), "sub" ); +// ele = XMLHandle( docC ).FirstChildElement( "element" ).FirstChild().ToElement(); +// XMLTest( "Handle, success, mutable", ele->Value(), "sub" ); } From 576120308439aa1ca8c771fc189d115fbf2adf27 Mon Sep 17 00:00:00 2001 From: Lee Thomason Date: Tue, 3 Apr 2012 16:43:22 -0700 Subject: [PATCH 5/7] trying to get template to work --- tinyxml2.h | 52 ++++++++++++++++++++++++++++------------------------ xmltest.cpp | 5 ++--- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/tinyxml2.h b/tinyxml2.h index b9cdbd7..5e562c7 100644 --- a/tinyxml2.h +++ b/tinyxml2.h @@ -1183,45 +1183,46 @@ private: TiXmlHandle handleCopy = handle; @endverbatim */ -class XMLHandle +template< class T > +class XMLHandleT { public: /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. - XMLHandle( XMLNode* _node ) { node = _node; } + XMLHandleT( T* _node ) { node = _node; } //XMLHandle( const XMLNode* _node ) { node = const_cast(_node); } - XMLHandle( XMLNode& _node ) { node = &_node; } + XMLHandleT( T& _node ) { node = &_node; } //XMLHandle( const XMLNode& _node ) { node = const_cast(&_node); } - XMLHandle( const XMLHandle& ref ) { node = ref.node; } + XMLHandleT( const XMLHandleT& ref ) { node = ref.node; } - XMLHandle operator=( XMLHandle ref ) { node = ref.node; return *this; } + XMLHandleT operator=( XMLHandleT ref ) { node = ref.node; return *this; } - XMLHandle FirstChild() { return XMLHandle( node ? node->FirstChild() : static_cast(0) ); } - const XMLHandle FirstChild() const { return XMLHandle( node ? node->FirstChild() : 0 ); } + XMLHandleT FirstChild() { return XMLHandleT( node ? node->FirstChild() : 0 ); } + const XMLHandleT FirstChild() const { return XMLHandleT( node ? node->FirstChild() : 0 ); } - XMLHandle FirstChildElement( const char* value=0 ) { return XMLHandle( node ? node->FirstChildElement( value ) : 0 ); } - const XMLHandle FirstChildElement( const char* value=0 ) const { return XMLHandle( node ? node->FirstChildElement( value ) : 0 ); } + XMLHandleT FirstChildElement( const char* value=0 ) { return XMLHandleT( node ? node->FirstChildElement( value ) : 0 ); } + const XMLHandleT FirstChildElement( const char* value=0 ) const { return XMLHandleT( node ? node->FirstChildElement( value ) : 0 ); } - XMLHandle LastChild() { return XMLHandle( node ? node->LastChild() : 0 ); } - const XMLHandle LastChild() const { return XMLHandle( node ? node->LastChild() : 0 ); } + XMLHandleT LastChild() { return XMLHandleT( node ? node->LastChild() : 0 ); } + const XMLHandleT LastChild() const { return XMLHandleT( node ? node->LastChild() : 0 ); } - XMLHandle LastChildElement( const char* _value=0 ) { return XMLHandle( node ? node->LastChildElement( _value ) : 0 ); } - const XMLHandle LastChildElement( const char* _value=0 ) const { return XMLHandle( node ? node->LastChildElement( _value ) : 0 ); } + XMLHandleT LastChildElement( const char* _value=0 ) { return XMLHandleT( node ? node->LastChildElement( _value ) : 0 ); } + const XMLHandleT LastChildElement( const char* _value=0 ) const { return XMLHandleT( node ? node->LastChildElement( _value ) : 0 ); } - XMLHandle PreviousSibling() { return XMLHandle( node ? node->PreviousSibling() : 0 ); } - const XMLHandle PreviousSibling() const { return XMLHandle( node ? node->PreviousSibling() : 0 ); } + XMLHandleT PreviousSibling() { return XMLHandleT( node ? node->PreviousSibling() : 0 ); } + const XMLHandleT PreviousSibling() const { return XMLHandleT( node ? node->PreviousSibling() : 0 ); } - XMLHandle PreviousSiblingElement( const char* _value=0 ) { return XMLHandle( node ? node->PreviousSiblingElement( _value ) : 0 ); } - const XMLHandle PreviousSiblingElement( const char* _value=0 ) const { return XMLHandle( node ? node->PreviousSiblingElement( _value ) : 0 ); } + XMLHandleT PreviousSiblingElement( const char* _value=0 ) { return XMLHandleT( node ? node->PreviousSiblingElement( _value ) : 0 ); } + const XMLHandleT PreviousSiblingElement( const char* _value=0 ) const { return XMLHandleT( node ? node->PreviousSiblingElement( _value ) : 0 ); } - XMLHandle NextSibling() { return XMLHandle( node ? node->NextSibling() : 0 ); } - const XMLHandle NextSibling() const { return XMLHandle( node ? node->NextSibling() : 0 ); } + XMLHandleT NextSibling() { return XMLHandleT( node ? node->NextSibling() : 0 ); } + const XMLHandleT NextSibling() const { return XMLHandleT( node ? node->NextSibling() : 0 ); } - XMLHandle NextSiblingElement( const char* _value=0 ) { return XMLHandle( node ? node->NextSiblingElement( _value ) : 0 ); } - const XMLHandle NextSiblingElement( const char* _value=0 ) const { return XMLHandle( node ? node->NextSiblingElement( _value ) : 0 ); } + XMLHandleT NextSiblingElement( const char* _value=0 ) { return XMLHandleT( node ? node->NextSiblingElement( _value ) : 0 ); } + const XMLHandleT NextSiblingElement( const char* _value=0 ) const { return XMLHandleT( node ? node->NextSiblingElement( _value ) : 0 ); } - XMLNode* ToNode() { return node; } - const XMLNode* ToNode() const { return node; } + T* ToNode() { return node; } + const T* ToNode() const { return node; } XMLElement* ToElement() { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } const XMLElement* ToElement() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } XMLText* ToText() { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); } @@ -1232,9 +1233,12 @@ public: const XMLDeclaration* ToDeclaration() const { return ( ( node && node->ToDeclaration() ) ? node->ToDeclaration() : 0 ); } private: - XMLNode* node; + T* node; }; +typedef XMLHandleT< XMLNode > XMLHandle; +typedef XMLHandleT< const XMLNode > XMLConstHandle; + /** Printing functionality. The XMLPrinter gives you more diff --git a/xmltest.cpp b/xmltest.cpp index 07d593c..ab2d568 100644 --- a/xmltest.cpp +++ b/xmltest.cpp @@ -736,9 +736,8 @@ int main( int /*argc*/, const char ** /*argv*/ ) XMLElement* ele = XMLHandle( doc ).FirstChildElement( "element" ).FirstChild().ToElement(); XMLTest( "Handle, success, mutable", ele->Value(), "sub" ); -// ele = XMLHandle( docC ).FirstChildElement( "element" ).FirstChild().ToElement(); -// XMLTest( "Handle, success, mutable", ele->Value(), "sub" ); - + const XMLElement* eleC = XMLConstHandle( docC ).FirstChildElement( "element" ).FirstChild().ToElement(); + XMLTest( "Handle, success, mutable", eleC->Value(), "sub" ); } From db0bbb60a14d6e5fe455dc75b1e0d0425dd2ac21 Mon Sep 17 00:00:00 2001 From: Lee Thomason Date: Wed, 4 Apr 2012 15:47:04 -0700 Subject: [PATCH 6/7] handles work --- tinyxml2.h | 4 ++-- xmltest.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tinyxml2.h b/tinyxml2.h index b9cdbd7..8740a7f 100644 --- a/tinyxml2.h +++ b/tinyxml2.h @@ -1169,8 +1169,8 @@ private: and correct to use: @verbatim - TiXmlHandle docHandle( &document ); - TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement(); + XMLHandle docHandle( &document ); + XMLElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild().NextSibling().ToElement(); if ( child2 ) { // do something useful diff --git a/xmltest.cpp b/xmltest.cpp index 07d593c..a2ebe5a 100644 --- a/xmltest.cpp +++ b/xmltest.cpp @@ -736,8 +736,8 @@ int main( int /*argc*/, const char ** /*argv*/ ) XMLElement* ele = XMLHandle( doc ).FirstChildElement( "element" ).FirstChild().ToElement(); XMLTest( "Handle, success, mutable", ele->Value(), "sub" ); -// ele = XMLHandle( docC ).FirstChildElement( "element" ).FirstChild().ToElement(); -// XMLTest( "Handle, success, mutable", ele->Value(), "sub" ); + const XMLElement* eleC = XMLHandle( docC ).FirstChildElement( "element" ).FirstChild().ToElement(); + XMLTest( "Handle, success, mutable", ele->Value(), "sub" ); } From ae209f6aedc55ab17b19b741ddc5c8215e6d6ed1 Mon Sep 17 00:00:00 2001 From: "Lee Thomason (grinliz)" Date: Wed, 4 Apr 2012 22:00:07 -0700 Subject: [PATCH 7/7] added docs. basic handles tests --- readme.txt | 3 +-- tinyxml2.h | 39 ++++++++++++++++++++++++++++----------- xmltest.cpp | 33 +++++++++++++++++++++++---------- 3 files changed, 52 insertions(+), 23 deletions(-) diff --git a/readme.txt b/readme.txt index ec2d015..fc9a0bf 100755 --- a/readme.txt +++ b/readme.txt @@ -11,8 +11,7 @@ github.com/leethomason/tinyxml2 The online HTML version of these docs: http://grinninglizard.com/tinyxml2docs/index.html -Where examples are in the "related pages" tab: -http://grinninglizard.com/tinyxml2docs/pages.html +Examples are in the "related pages" tab of the HTML docs.

What it does.

diff --git a/tinyxml2.h b/tinyxml2.h index 0d58dc3..0acf9d8 100644 --- a/tinyxml2.h +++ b/tinyxml2.h @@ -1133,7 +1133,7 @@ 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 + an incredibly useful thing. Note that XMLHandle is not part of the TinyXML DOM structure. It is a separate utility class. Take an example: @@ -1150,23 +1150,23 @@ private: easy to write a *lot* of code that looks like: @verbatim - TiXmlElement* root = document.FirstChildElement( "Document" ); + XMLElement* root = document.FirstChildElement( "Document" ); if ( root ) { - TiXmlElement* element = root->FirstChildElement( "Element" ); + XMLElement* element = root->FirstChildElement( "Element" ); if ( element ) { - TiXmlElement* child = element->FirstChildElement( "Child" ); + XMLElement* child = element->FirstChildElement( "Child" ); if ( child ) { - TiXmlElement* child2 = child->NextSiblingElement( "Child" ); + XMLElement* child2 = child->NextSiblingElement( "Child" ); if ( child2 ) { // Finally do something useful. @endverbatim - And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity - of such code. A TiXmlHandle checks for null pointers so it is perfectly safe + 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 @@ -1181,33 +1181,49 @@ private: It is also safe to copy handles - internally they are nothing more than node pointers. @verbatim - TiXmlHandle handleCopy = handle; + 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: @@ -1216,7 +1232,8 @@ private: /** - A variant of the XMLHandle class for working with const XMLNodes and Documents. + 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 { diff --git a/xmltest.cpp b/xmltest.cpp index fb5348a..6a1d330 100644 --- a/xmltest.cpp +++ b/xmltest.cpp @@ -94,12 +94,12 @@ int example_2() int example_3() { - static const char* xml = - "" - "" - "" - "A Midsummer Night's Dream" - ""; + static const char* xml = + "" + "" + "" + "A Midsummer Night's Dream" + ""; XMLDocument doc; doc.Parse( xml ); @@ -756,16 +756,29 @@ int main( int /*argc*/, const char ** /*argv*/ ) static const char* xml = "Text"; XMLDocument doc; doc.Parse( xml ); - const XMLDocument& docC = doc; XMLElement* ele = XMLHandle( doc ).FirstChildElement( "element" ).FirstChild().ToElement(); XMLTest( "Handle, success, mutable", ele->Value(), "sub" ); - const XMLElement* eleC = XMLConstHandle( docC ).FirstChildElement( "element" ).FirstChild().ToElement(); - XMLTest( "Handle, success, mutable", eleC->Value(), "sub" ); - + XMLHandle docH( doc ); + ele = docH.FirstChildElement( "none" ).FirstChildElement( "element" ).ToElement(); + XMLTest( "Handle, dne, mutable", 0, (int)ele ); } + { + static const char* xml = "Text"; + 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 -------------- {