From b1ff002ba630699a9a55be14c16e73a80b054432 Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Tue, 27 Mar 2012 00:50:52 +0100 Subject: [PATCH 01/16] Added cmake support --- CMakeLists.txt | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..3d9c670 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,48 @@ +cmake_minimum_required(VERSION 2.6 FATAL_ERROR) +cmake_policy(VERSION 2.6) + +project(tinyxml2) +#enable_testing() + +#CMAKE_BUILD_TOOL + +################################ +# Add common source + +include_directories("${CMAKE_CURRENT_SOURCE_DIR}/.") + +################################ +# Add custom target to copy all data + +set(TARGET_DATA_COPY DATA_COPY) +if(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR}) + add_custom_target( + ${TARGET_DATA_COPY} + COMMAND ${CMAKE_COMMAND} -E echo "In source build") +else(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR}) + add_custom_target( + ${TARGET_DATA_COPY} + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/dream.xml ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/utf8test.xml ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/utf8testverify.xml ${CMAKE_CURRENT_BINARY_DIR}) +endif(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR}) + +set(OGL_DATA_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/data) + +################################ +# Add definitions + +if(MSVC) + add_definitions(-D_CRT_SECURE_NO_WARNINGS) +endif(MSVC) + +################################ +# Add targets + +add_library(tinyxml2 STATIC tinyxml2.cpp tinyxml2.h) + +add_executable(test xmltest.cpp) +add_dependencies(test tinyxml2) +add_dependencies(test ${TARGET_DATA_COPY}) +target_link_libraries(test tinyxml2) +#add_test(test ${SAMPLE_NAME} COMMAND $) From 3ffdd39dbf44c8a9dc40bbc74cebd747a8d93c94 Mon Sep 17 00:00:00 2001 From: Lee Thomason Date: Wed, 28 Mar 2012 17:27:55 -0700 Subject: [PATCH 02/16] 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 03/16] 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 04/16] 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 05/16] 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 06/16] 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 07/16] 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 -------------- { From 2f6e476e5fec107f1e3c191fa085140c50421184 Mon Sep 17 00:00:00 2001 From: Lee Thomason Date: Thu, 5 Apr 2012 08:52:07 -0700 Subject: [PATCH 08/16] added a few notes to the readme about building --- readme.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/readme.txt b/readme.txt index ec2d015..7ac8aa0 100755 --- a/readme.txt +++ b/readme.txt @@ -243,8 +243,9 @@ And additionally a test file:
  • xmltest.cpp
  • -Simply compile and run. There is a visual studio 2010 project included. - +Simply compile and run. There is a visual studio 2010 project included, a simple Makefile, +an XCode project, and a cmake CMakeLists.txt included to help you. The top of tinyxml.h +even has a simple g++ command line if you are are *nix and don't want to use a build system.

    Documentation

    From 26e15df1e2039aa326ad033ab32f94ea08189bc2 Mon Sep 17 00:00:00 2001 From: Bruno Dias Date: Fri, 6 Apr 2012 00:39:48 -0300 Subject: [PATCH 09/16] update the xcode project. --- tinyxml2/tinyxml2.xcodeproj/project.pbxproj | 41 +++++++++++++++------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/tinyxml2/tinyxml2.xcodeproj/project.pbxproj b/tinyxml2/tinyxml2.xcodeproj/project.pbxproj index 7b1b7a2..a6b7b61 100644 --- a/tinyxml2/tinyxml2.xcodeproj/project.pbxproj +++ b/tinyxml2/tinyxml2.xcodeproj/project.pbxproj @@ -7,11 +7,11 @@ objects = { /* Begin PBXBuildFile section */ - 037AE8A4151E692700E0F29F /* tinyxml2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 037AE8A1151E692700E0F29F /* tinyxml2.cpp */; }; 037AE8A5151E692700E0F29F /* xmltest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 037AE8A3151E692700E0F29F /* xmltest.cpp */; }; 037AE9BE151E694400E0F29F /* dream.xml in CopyFiles */ = {isa = PBXBuildFile; fileRef = 037AE062151CCC6D00E0F29F /* dream.xml */; }; 037AE9BF151E694400E0F29F /* utf8test.xml in CopyFiles */ = {isa = PBXBuildFile; fileRef = 037AE065151CCC6D00E0F29F /* utf8test.xml */; }; 037AE9C0151E694400E0F29F /* utf8testverify.xml in CopyFiles */ = {isa = PBXBuildFile; fileRef = 037AE066151CCC6D00E0F29F /* utf8testverify.xml */; }; + 03F28B53152E9B1B00D4CD90 /* tinyxml2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 03F28B4A152E9B1B00D4CD90 /* tinyxml2.cpp */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -34,9 +34,9 @@ 037AE065151CCC6D00E0F29F /* utf8test.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = utf8test.xml; sourceTree = ""; }; 037AE066151CCC6D00E0F29F /* utf8testverify.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = utf8testverify.xml; sourceTree = ""; }; 037AE86D151E685F00E0F29F /* tinyxml2 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = tinyxml2; sourceTree = BUILT_PRODUCTS_DIR; }; - 037AE8A1151E692700E0F29F /* tinyxml2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tinyxml2.cpp; path = ../tinyxml2.cpp; sourceTree = ""; }; - 037AE8A2151E692700E0F29F /* tinyxml2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tinyxml2.h; path = ../tinyxml2.h; sourceTree = ""; }; 037AE8A3151E692700E0F29F /* xmltest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = xmltest.cpp; path = ../xmltest.cpp; sourceTree = SOURCE_ROOT; }; + 03F28B4A152E9B1B00D4CD90 /* tinyxml2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinyxml2.cpp; sourceTree = ""; }; + 03F28B4B152E9B1B00D4CD90 /* tinyxml2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tinyxml2.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -53,30 +53,29 @@ 037AE056151CCC5200E0F29F = { isa = PBXGroup; children = ( - 037AE06A151CCC7C00E0F29F /* resources */, - 037AE069151CCC7000E0F29F /* src */, + 037AE069151CCC7000E0F29F /* Classes */, + 037AE06A151CCC7C00E0F29F /* Resources */, + 03F28B60152E9B4C00D4CD90 /* Libraries */, 037AE06F151CCCB900E0F29F /* Products */, ); sourceTree = ""; }; - 037AE069151CCC7000E0F29F /* src */ = { + 037AE069151CCC7000E0F29F /* Classes */ = { isa = PBXGroup; children = ( - 037AE8A1151E692700E0F29F /* tinyxml2.cpp */, - 037AE8A2151E692700E0F29F /* tinyxml2.h */, 037AE8A3151E692700E0F29F /* xmltest.cpp */, ); - name = src; + name = Classes; sourceTree = ""; }; - 037AE06A151CCC7C00E0F29F /* resources */ = { + 037AE06A151CCC7C00E0F29F /* Resources */ = { isa = PBXGroup; children = ( 037AE062151CCC6D00E0F29F /* dream.xml */, 037AE065151CCC6D00E0F29F /* utf8test.xml */, 037AE066151CCC6D00E0F29F /* utf8testverify.xml */, ); - name = resources; + name = Resources; path = ..; sourceTree = ""; }; @@ -88,6 +87,24 @@ name = Products; sourceTree = ""; }; + 03F28AD7152E9B1B00D4CD90 /* tinyxml2 */ = { + isa = PBXGroup; + children = ( + 03F28B4A152E9B1B00D4CD90 /* tinyxml2.cpp */, + 03F28B4B152E9B1B00D4CD90 /* tinyxml2.h */, + ); + name = tinyxml2; + path = ..; + sourceTree = SOURCE_ROOT; + }; + 03F28B60152E9B4C00D4CD90 /* Libraries */ = { + isa = PBXGroup; + children = ( + 03F28AD7152E9B1B00D4CD90 /* tinyxml2 */, + ); + name = Libraries; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -138,8 +155,8 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 037AE8A4151E692700E0F29F /* tinyxml2.cpp in Sources */, 037AE8A5151E692700E0F29F /* xmltest.cpp in Sources */, + 03F28B53152E9B1B00D4CD90 /* tinyxml2.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; From 598c13efa86e1d81198ce49f50904b90b54b1d39 Mon Sep 17 00:00:00 2001 From: "Lee Thomason (grinliz)" Date: Fri, 6 Apr 2012 21:18:23 -0700 Subject: [PATCH 10/16] fix the safe function behavior --- tinyxml2.cpp | 7 +++---- tinyxml2.h | 28 ++++++++++++++++------------ 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/tinyxml2.cpp b/tinyxml2.cpp index 9e92ae2..72c2dac 100644 --- a/tinyxml2.cpp +++ b/tinyxml2.cpp @@ -24,7 +24,6 @@ distribution. #include "tinyxml2.h" #if 1 - #include #include #include #include @@ -998,7 +997,7 @@ void XMLAttribute::SetAttribute( const char* v ) void XMLAttribute::SetAttribute( int v ) { char buf[BUF_SIZE]; - TIXML_SNPRINTF( buf, BUF_SIZE-1, "%d", v ); + TIXML_SNPRINTF( buf, BUF_SIZE, "%d", v ); value.SetStr( buf ); } @@ -1534,10 +1533,10 @@ void XMLPrinter::Print( const char* format, ... ) int len = -1; int expand = 1000; while ( len < 0 ) { - len = vsnprintf_s( accumulator.Mem(), accumulator.Capacity(), accumulator.Capacity()-1, format, va ); + len = vsnprintf_s( accumulator.Mem(), accumulator.Capacity(), _TRUNCATE, format, va ); if ( len < 0 ) { - accumulator.PushArr( expand ); expand *= 3/2; + accumulator.PushArr( expand ); } } char* p = buffer.PushArr( len ) - 1; diff --git a/tinyxml2.h b/tinyxml2.h index bf00964..f9348ab 100644 --- a/tinyxml2.h +++ b/tinyxml2.h @@ -29,6 +29,7 @@ distribution. #include #include #include + #include #else // Not completely sure all the interesting systems // can handle the new headers; can switch this if @@ -70,27 +71,30 @@ distribution. #endif -// Deprecated library function hell. Compilers want to use the -// new safe versions. This probably doesn't fully address the problem, -// but it gets closer. There are too many compilers for me to fully -// test. If you get compilation troubles, undefine TIXML_SAFE - #if defined(_MSC_VER) && (_MSC_VER >= 1400 ) // Microsoft visual studio, version 2005 and higher. - #define TIXML_SNPRINTF _snprintf_s + /*int _snprintf_s( + char *buffer, + size_t sizeOfBuffer, + size_t count, + const char *format [, + argument] ... + );*/ + inline int TIXML_SNPRINTF( char* buffer, size_t size, const char* format, ... ) { + va_list va; + va_start( va, format ); + int result = vsnprintf_s( buffer, size, _TRUNCATE, format, va ); + va_end( va ); + return result; + } #define TIXML_SSCANF sscanf_s -#elif defined(_MSC_VER) && (_MSC_VER >= 1200 ) - // Microsoft visual studio, version 6 and higher. - //#pragma message( "Using _sn* functions." ) - #define TIXML_SNPRINTF _snprintf - #define TIXML_SSCANF sscanf #elif defined(__GNUC__) && (__GNUC__ >= 3 ) // GCC version 3 and higher //#warning( "Using sn* functions." ) #define TIXML_SNPRINTF snprintf #define TIXML_SSCANF sscanf #else - #define TIXML_SNPRINTF snprintf + #define TIXML_SNPRINTF snprintf( buf, size, x ) snprintf( buf, size, x ) #define TIXML_SSCANF sscanf #endif From a4a36ba3c2c98988b7a6a774061028014678c7f2 Mon Sep 17 00:00:00 2001 From: "Lee Thomason (grinliz)" Date: Fri, 6 Apr 2012 21:24:29 -0700 Subject: [PATCH 11/16] remove random -1 in length --- tinyxml2.cpp | 18 ++++++++---------- xmltest.cpp | 22 ++++++++++++++++------ 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/tinyxml2.cpp b/tinyxml2.cpp index 72c2dac..f6998ea 100644 --- a/tinyxml2.cpp +++ b/tinyxml2.cpp @@ -1005,7 +1005,7 @@ void XMLAttribute::SetAttribute( int v ) void XMLAttribute::SetAttribute( unsigned v ) { char buf[BUF_SIZE]; - TIXML_SNPRINTF( buf, BUF_SIZE-1, "%u", v ); + TIXML_SNPRINTF( buf, BUF_SIZE, "%u", v ); value.SetStr( buf ); } @@ -1013,21 +1013,21 @@ void XMLAttribute::SetAttribute( unsigned v ) void XMLAttribute::SetAttribute( bool v ) { char buf[BUF_SIZE]; - TIXML_SNPRINTF( buf, BUF_SIZE-1, "%d", v ? 1 : 0 ); + TIXML_SNPRINTF( buf, BUF_SIZE, "%d", v ? 1 : 0 ); value.SetStr( buf ); } void XMLAttribute::SetAttribute( double v ) { char buf[BUF_SIZE]; - TIXML_SNPRINTF( buf, BUF_SIZE-1, "%f", v ); + TIXML_SNPRINTF( buf, BUF_SIZE, "%f", v ); value.SetStr( buf ); } void XMLAttribute::SetAttribute( float v ) { char buf[BUF_SIZE]; - TIXML_SNPRINTF( buf, BUF_SIZE-1, "%f", v ); + TIXML_SNPRINTF( buf, BUF_SIZE, "%f", v ); value.SetStr( buf ); } @@ -1480,11 +1480,9 @@ void XMLDocument::PrintError() const if ( errorStr1 ) { TIXML_SNPRINTF( buf1, LEN, "%s", errorStr1 ); - buf1[LEN-1] = 0; } if ( errorStr2 ) { TIXML_SNPRINTF( buf2, LEN, "%s", errorStr2 ); - buf2[LEN-1] = 0; } printf( "XMLDocument error id=%d str1=%s str2=%s\n", @@ -1643,7 +1641,7 @@ void XMLPrinter::PushAttribute( const char* name, const char* value ) void XMLPrinter::PushAttribute( const char* name, int v ) { char buf[BUF_SIZE]; - TIXML_SNPRINTF( buf, BUF_SIZE-1, "%d", v ); + TIXML_SNPRINTF( buf, BUF_SIZE, "%d", v ); PushAttribute( name, buf ); } @@ -1651,7 +1649,7 @@ void XMLPrinter::PushAttribute( const char* name, int v ) void XMLPrinter::PushAttribute( const char* name, unsigned v ) { char buf[BUF_SIZE]; - TIXML_SNPRINTF( buf, BUF_SIZE-1, "%u", v ); + TIXML_SNPRINTF( buf, BUF_SIZE, "%u", v ); PushAttribute( name, buf ); } @@ -1659,7 +1657,7 @@ void XMLPrinter::PushAttribute( const char* name, unsigned v ) void XMLPrinter::PushAttribute( const char* name, bool v ) { char buf[BUF_SIZE]; - TIXML_SNPRINTF( buf, BUF_SIZE-1, "%d", v ? 1 : 0 ); + TIXML_SNPRINTF( buf, BUF_SIZE, "%d", v ? 1 : 0 ); PushAttribute( name, buf ); } @@ -1667,7 +1665,7 @@ void XMLPrinter::PushAttribute( const char* name, bool v ) void XMLPrinter::PushAttribute( const char* name, double v ) { char buf[BUF_SIZE]; - TIXML_SNPRINTF( buf, BUF_SIZE-1, "%f", v ); + TIXML_SNPRINTF( buf, BUF_SIZE, "%f", v ); PushAttribute( name, buf ); } diff --git a/xmltest.cpp b/xmltest.cpp index bb5bdfb..29809e8 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 ); @@ -751,6 +751,16 @@ int main( int /*argc*/, const char ** /*argv*/ ) XMLTest( "Clone and Equal", 4, count ); } + { + // This shouldn't crash. + XMLDocument doc; + if(XML_NO_ERROR != doc.LoadFile( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" )) + { + doc.PrintError(); + } + XMLTest( "Error in snprinf handling.", true, doc.Error() ); + } + // ----------- Performance tracking -------------- { #if defined( _MSC_VER ) From b9e791fa4e4950143f7bbe9a86351cc7abc7490a Mon Sep 17 00:00:00 2001 From: "Lee Thomason (grinliz)" Date: Fri, 6 Apr 2012 21:27:10 -0700 Subject: [PATCH 12/16] simplify safe logic --- tinyxml2.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tinyxml2.h b/tinyxml2.h index f9348ab..251d2ad 100644 --- a/tinyxml2.h +++ b/tinyxml2.h @@ -88,14 +88,11 @@ distribution. return result; } #define TIXML_SSCANF sscanf_s -#elif defined(__GNUC__) && (__GNUC__ >= 3 ) +#else // GCC version 3 and higher //#warning( "Using sn* functions." ) #define TIXML_SNPRINTF snprintf #define TIXML_SSCANF sscanf -#else - #define TIXML_SNPRINTF snprintf( buf, size, x ) snprintf( buf, size, x ) - #define TIXML_SSCANF sscanf #endif static const int TIXML2_MAJOR_VERSION = 0; From 8871cd84379afcdd1743e80b8c5bfde0cdf2f0c9 Mon Sep 17 00:00:00 2001 From: "Lee Thomason (grinliz)" Date: Fri, 6 Apr 2012 21:40:08 -0700 Subject: [PATCH 13/16] add xmltest.h as a place to put the example docs, so they don't pollute the main file' --- dox | 2 +- tinyxml2.h | 92 ---------------------------------------------------- xmltest.h | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 93 deletions(-) create mode 100755 xmltest.h diff --git a/dox b/dox index 3a18853..7997ec0 100755 --- a/dox +++ b/dox @@ -661,7 +661,7 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = tinyxml2.h readme.txt +INPUT = tinyxml2.h xmltest.h readme.txt # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is diff --git a/tinyxml2.h b/tinyxml2.h index 251d2ad..f6a455d 100644 --- a/tinyxml2.h +++ b/tinyxml2.h @@ -1253,96 +1253,4 @@ private: } // tinyxml2 -// What follows is the docs for the examples. -// I'd like the docs to be just before the -// actual examples in xmltest.cpp, but I -// can't seem to get doxygen to do that. It -// would be a wonderful patch if anyone figures -// it out. - -/** @page Example-1 Load an XML File - * @dontinclude ./xmltest.cpp - * Basic XML file loading. - * The basic syntax to load an XML file from - * disk and check for an error. (ErrorID() - * will return 0 for no error.) - * @skip example_1() - * @until } - */ - - -/** @page Example-2 Parse an XML from char buffer - * @dontinclude ./xmltest.cpp - * Basic XML string parsing. - * The basic syntax to parse an XML for - * a char* and check for an error. (ErrorID() - * will return 0 for no error.) - * @skip example_2() - * @until } - */ - -/** @page Example-3 Get information out of XML - @dontinclude ./xmltest.cpp - In this example, we navigate a simple XML - file, and read some interesting text. Note - that this is examlpe doesn't use error - checking; working code should check for null - pointers when walking an XML tree, or use - XMLHandle. - - (The XML is an excerpt from "dream.xml"). - - @skip example_3 - @until "; - - The structure of the XML file is: - -
      -
    • (declaration)
    • -
    • (dtd stuff)
    • -
    • Element "PLAY"
    • -
        -
      • Element "TITLE"
      • -
          -
        • Text "A Midsummer Night's Dream"
        • -
        -
      -
    - - For this example, we want to print out the - title of the play. The text of the title (what - we want) is child of the "TITLE" element which - is a child of the "PLAY" element. - - We want to skip the declaration and dtd, so the - method FirstChildElement() is a good choice. The - FirstChildElement() of the Document is the "PLAY" - Element, the FirstChildElement() of the "PLAY" Element - is the "TITLE" Element. - - @until ( "TITLE" ); - - We can then use the convenience function GetText() - to get the title of the play. - - @until title ); - - Text is just another Node in the XML DOM. And in - fact you should be a little cautious with it, as - text nodes can contain elements. - - @verbatim - Consider: A Midsummer Night's Dream - @endverbatim - - It is more correct to actually query the Text Node - if in doubt: - - @until title ); - - Noting that here we use FirstChild() since we are - looking for XMLText, not an element, and ToText() - is a cast from a Node to a XMLText. -*/ - #endif // TINYXML2_INCLUDED diff --git a/xmltest.h b/xmltest.h new file mode 100755 index 0000000..73a48c0 --- /dev/null +++ b/xmltest.h @@ -0,0 +1,94 @@ +// Purely doxygen documentation + + +// What follows is the docs for the examples. +// I'd like the docs to be just before the +// actual examples in xmltest.cpp, but I +// can't seem to get doxygen to do that. It +// would be a wonderful patch if anyone figures +// it out. + +/** @page Example-1 Load an XML File + * @dontinclude ./xmltest.cpp + * Basic XML file loading. + * The basic syntax to load an XML file from + * disk and check for an error. (ErrorID() + * will return 0 for no error.) + * @skip example_1() + * @until } + */ + + +/** @page Example-2 Parse an XML from char buffer + * @dontinclude ./xmltest.cpp + * Basic XML string parsing. + * The basic syntax to parse an XML for + * a char* and check for an error. (ErrorID() + * will return 0 for no error.) + * @skip example_2() + * @until } + */ + +/** @page Example-3 Get information out of XML + @dontinclude ./xmltest.cpp + In this example, we navigate a simple XML + file, and read some interesting text. Note + that this is examlpe doesn't use error + checking; working code should check for null + pointers when walking an XML tree, or use + XMLHandle. + + (The XML is an excerpt from "dream.xml"). + + @skip example_3 + @until "; + + The structure of the XML file is: + +
      +
    • (declaration)
    • +
    • (dtd stuff)
    • +
    • Element "PLAY"
    • +
        +
      • Element "TITLE"
      • +
          +
        • Text "A Midsummer Night's Dream"
        • +
        +
      +
    + + For this example, we want to print out the + title of the play. The text of the title (what + we want) is child of the "TITLE" element which + is a child of the "PLAY" element. + + We want to skip the declaration and dtd, so the + method FirstChildElement() is a good choice. The + FirstChildElement() of the Document is the "PLAY" + Element, the FirstChildElement() of the "PLAY" Element + is the "TITLE" Element. + + @until ( "TITLE" ); + + We can then use the convenience function GetText() + to get the title of the play. + + @until title ); + + Text is just another Node in the XML DOM. And in + fact you should be a little cautious with it, as + text nodes can contain elements. + + @verbatim + Consider: A Midsummer Night's Dream + @endverbatim + + It is more correct to actually query the Text Node + if in doubt: + + @until title ); + + Noting that here we use FirstChild() since we are + looking for XMLText, not an element, and ToText() + is a cast from a Node to a XMLText. +*/ From 81da1fb26bf909f3aefd1984baf0a6c7b2784670 Mon Sep 17 00:00:00 2001 From: Ken Miller Date: Mon, 9 Apr 2012 23:32:26 -0500 Subject: [PATCH 14/16] Made SaveFile symmetrical with LoadFile Added overload taking a FILE pointer Return error code (if any) instead of void --- tinyxml2.cpp | 21 ++++++++++++++------- tinyxml2.h | 12 +++++++++++- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/tinyxml2.cpp b/tinyxml2.cpp index f6998ea..4ce9b32 100644 --- a/tinyxml2.cpp +++ b/tinyxml2.cpp @@ -1407,7 +1407,7 @@ int XMLDocument::LoadFile( FILE* fp ) } -void XMLDocument::SaveFile( const char* filename ) +int XMLDocument::SaveFile( const char* filename ) { #if defined(_MSC_VER) #pragma warning ( push ) @@ -1417,14 +1417,21 @@ void XMLDocument::SaveFile( const char* filename ) #if defined(_MSC_VER) #pragma warning ( pop ) #endif - if ( fp ) { - XMLPrinter stream( fp ); - Print( &stream ); - fclose( fp ); - } - else { + if ( !fp ) { SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, filename, 0 ); + return errorID; } + SaveFile(fp); + fclose( fp ); + return errorID; +} + + +int XMLDocument::SaveFile( FILE* fp ) +{ + XMLPrinter stream( fp ); + Print( &stream ); + return errorID; } diff --git a/tinyxml2.h b/tinyxml2.h index feffd36..769882b 100644 --- a/tinyxml2.h +++ b/tinyxml2.h @@ -1024,8 +1024,18 @@ public: int LoadFile( FILE* ); /** Save the XML file to disk. + Returns XML_NO_ERROR (0) on success, or + an errorID. */ - void SaveFile( const char* filename ); + int SaveFile( const char* filename ); + /** + Save the XML file to disk. You are responsible + for providing and closing the FILE*. + + Returns XML_NO_ERROR (0) on success, or + an errorID. + */ + int SaveFile( FILE* ); bool ProcessEntities() const { return processEntities; } From d11cd169e65913e395892920c697794b328205c7 Mon Sep 17 00:00:00 2001 From: Lee Thomason Date: Thu, 12 Apr 2012 08:35:36 -0700 Subject: [PATCH 15/16] minor whitespace cleanup --- tinyxml2.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tinyxml2.h b/tinyxml2.h index 769882b..76e47ac 100644 --- a/tinyxml2.h +++ b/tinyxml2.h @@ -1008,26 +1008,30 @@ public: an errorID. */ int Parse( const char* xml ); + /** Load an XML file from disk. Returns XML_NO_ERROR (0) on success, or an errorID. - */ + */ int LoadFile( const char* filename ); + /** Load an XML file from disk. You are responsible for providing and closing the FILE*. Returns XML_NO_ERROR (0) on success, or an errorID. - */ + */ int LoadFile( FILE* ); + /** Save the XML file to disk. Returns XML_NO_ERROR (0) on success, or an errorID. */ int SaveFile( const char* filename ); + /** Save the XML file to disk. You are responsible for providing and closing the FILE*. From d0b19df88c25d165187d5d89cd28da26a2a5845e Mon Sep 17 00:00:00 2001 From: Lee Thomason Date: Thu, 12 Apr 2012 08:41:37 -0700 Subject: [PATCH 16/16] fix sleazy cast causing compilation issue --- xmltest.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xmltest.cpp b/xmltest.cpp index 5e48d50..0991e2d 100644 --- a/xmltest.cpp +++ b/xmltest.cpp @@ -772,7 +772,7 @@ int main( int /*argc*/, const char ** /*argv*/ ) XMLHandle docH( doc ); ele = docH.FirstChildElement( "none" ).FirstChildElement( "element" ).ToElement(); - XMLTest( "Handle, dne, mutable", 0, (int)ele ); + XMLTest( "Handle, dne, mutable", false, ele != 0 ); } { @@ -785,7 +785,7 @@ int main( int /*argc*/, const char ** /*argv*/ ) XMLTest( "Handle, success, const", ele->Value(), "sub" ); ele = docH.FirstChildElement( "none" ).FirstChildElement( "element" ).ToElement(); - XMLTest( "Handle, dne, const", 0, (int)ele ); + XMLTest( "Handle, dne, const", false, ele != 0 ); }