| /* |
| www.sourceforge.net/projects/tinyxml |
| Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com) |
| |
| This software is provided 'as-is', without any express or implied |
| warranty. In no event will the authors be held liable for any |
| damages arising from the use of this software. |
| |
| Permission is granted to anyone to use this software for any |
| purpose, including commercial applications, and to alter it and |
| redistribute it freely, subject to the following restrictions: |
| |
| 1. The origin of this software must not be misrepresented; you must |
| not claim that you wrote the original software. If you use this |
| software in a product, an acknowledgment in the product documentation |
| would be appreciated but is not required. |
| |
| 2. Altered source versions must be plainly marked as such, and |
| must not be misrepresented as being the original software. |
| |
| 3. This notice may not be removed or altered from any source |
| distribution. |
| */ |
| |
| |
| #ifndef TINYXML_INCLUDED |
| #define TINYXML_INCLUDED |
| |
| #ifdef _MSC_VER |
| #pragma warning( push ) |
| #pragma warning( disable : 4530 ) |
| #pragma warning( disable : 4786 ) |
| #endif |
| |
| #include <ctype.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <assert.h> |
| |
| // Help out windows: |
| #if defined( _DEBUG ) && !defined( DEBUG ) |
| #define DEBUG |
| #endif |
| |
| #if defined( DEBUG ) && defined( _MSC_VER ) |
| #include <windows.h> |
| #define TIXML_LOG OutputDebugString |
| #else |
| #define TIXML_LOG printf |
| #endif |
| |
| #ifdef TIXML_USE_STL |
| #include <string> |
| #include <iostream> |
| #define TIXML_STRING std::string |
| #define TIXML_ISTREAM std::istream |
| #define TIXML_OSTREAM std::ostream |
| #else |
| #include "tinystr.h" |
| #define TIXML_STRING TiXmlString |
| #define TIXML_OSTREAM TiXmlOutStream |
| #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 |
| |
| #define TIXML_SAFE // TinyXml isn't fully buffer overrun protected, safe code. This is work in progress. |
| #ifdef TIXML_SAFE |
| #if defined(_MSC_VER) && (_MSC_VER >= 1200 ) |
| // Microsoft visual studio, version 6 and higher. |
| //#pragma message( "Using _sn* functions." ) |
| #define TIXML_SNPRINTF _snprintf |
| #define TIXML_SNSCANF _snscanf |
| #elif defined(__GNUC__) && (__GNUC__ >= 3 ) |
| // GCC version 3 and higher.s |
| //#warning( "Using sn* functions." ) |
| #define TIXML_SNPRINTF snprintf |
| #define TIXML_SNSCANF snscanf |
| #endif |
| #endif |
| |
| class TiXmlDocument; |
| class TiXmlElement; |
| class TiXmlComment; |
| class TiXmlUnknown; |
| class TiXmlAttribute; |
| class TiXmlText; |
| class TiXmlDeclaration; |
| class TiXmlParsingData; |
| |
| const int TIXML_MAJOR_VERSION = 2; |
| const int TIXML_MINOR_VERSION = 4; |
| const int TIXML_PATCH_VERSION = 0; |
| |
| /* Internal structure for tracking location of items |
| in the XML file. |
| */ |
| struct TiXmlCursor |
| { |
| TiXmlCursor() { Clear(); } |
| void Clear() { row = col = -1; } |
| |
| int row; // 0 based. |
| int col; // 0 based. |
| }; |
| |
| |
| // Only used by Attribute::Query functions |
| enum |
| { |
| TIXML_SUCCESS, |
| TIXML_NO_ATTRIBUTE, |
| TIXML_WRONG_TYPE |
| }; |
| |
| |
| // Used by the parsing routines. |
| enum TiXmlEncoding |
| { |
| TIXML_ENCODING_UNKNOWN, |
| TIXML_ENCODING_UTF8, |
| TIXML_ENCODING_LEGACY |
| }; |
| |
| const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN; |
| |
| /** TiXmlBase is a base class for every class in TinyXml. |
| It does little except to establish that TinyXml classes |
| can be printed and provide some utility functions. |
| |
| In XML, the document and elements can contain |
| other elements and other types of nodes. |
| |
| @verbatim |
| A Document can contain: Element (container or leaf) |
| Comment (leaf) |
| Unknown (leaf) |
| Declaration( leaf ) |
| |
| An Element can contain: Element (container or leaf) |
| Text (leaf) |
| Attributes (not on tree) |
| Comment (leaf) |
| Unknown (leaf) |
| |
| A Decleration contains: Attributes (not on tree) |
| @endverbatim |
| */ |
| class TiXmlBase |
| { |
| friend class TiXmlNode; |
| friend class TiXmlElement; |
| friend class TiXmlDocument; |
| |
| public: |
| TiXmlBase() : userData(0) {} |
| virtual ~TiXmlBase() {} |
| |
| /** All TinyXml classes can print themselves to a filestream. |
| This is a formatted print, and will insert tabs and newlines. |
| |
| (For an unformatted stream, use the << operator.) |
| */ |
| virtual void Print( FILE* cfile, int depth ) const = 0; |
| |
| /** The world does not agree on whether white space should be kept or |
| not. In order to make everyone happy, these global, static functions |
| are provided to set whether or not TinyXml will condense all white space |
| into a single space or not. The default is to condense. Note changing this |
| values is not thread safe. |
| */ |
| static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; } |
| |
| /// Return the current white space setting. |
| static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace; } |
| |
| /** Return the position, in the original source file, of this node or attribute. |
| The row and column are 1-based. (That is the first row and first column is |
| 1,1). If the returns values are 0 or less, then the parser does not have |
| a row and column value. |
| |
| Generally, the row and column value will be set when the TiXmlDocument::Load(), |
| TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set |
| when the DOM was created from operator>>. |
| |
| The values reflect the initial load. Once the DOM is modified programmatically |
| (by adding or changing nodes and attributes) the new values will NOT update to |
| reflect changes in the document. |
| |
| There is a minor performance cost to computing the row and column. Computation |
| can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value. |
| |
| @sa TiXmlDocument::SetTabSize() |
| */ |
| int Row() const { return location.row + 1; } |
| int Column() const { return location.col + 1; } ///< See Row() |
| |
| void SetUserData( void* user ) { userData = user; } |
| void* GetUserData() { return userData; } |
| |
| // Table that returs, for a given lead byte, the total number of bytes |
| // in the UTF-8 sequence. |
| static const int utf8ByteTable[256]; |
| |
| virtual const char* Parse( const char* p, |
| TiXmlParsingData* data, |
| TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0; |
| |
| enum |
| { |
| TIXML_NO_ERROR = 0, |
| TIXML_ERROR, |
| TIXML_ERROR_OPENING_FILE, |
| TIXML_ERROR_OUT_OF_MEMORY, |
| TIXML_ERROR_PARSING_ELEMENT, |
| TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, |
| TIXML_ERROR_READING_ELEMENT_VALUE, |
| TIXML_ERROR_READING_ATTRIBUTES, |
| TIXML_ERROR_PARSING_EMPTY, |
| TIXML_ERROR_READING_END_TAG, |
| TIXML_ERROR_PARSING_UNKNOWN, |
| TIXML_ERROR_PARSING_COMMENT, |
| TIXML_ERROR_PARSING_DECLARATION, |
| TIXML_ERROR_DOCUMENT_EMPTY, |
| TIXML_ERROR_EMBEDDED_NULL, |
| TIXML_ERROR_PARSING_CDATA, |
| |
| TIXML_ERROR_STRING_COUNT |
| }; |
| |
| protected: |
| |
| // See STL_STRING_BUG |
| // Utility class to overcome a bug. |
| class StringToBuffer |
| { |
| public: |
| StringToBuffer( const TIXML_STRING& str ); |
| ~StringToBuffer(); |
| char* buffer; |
| }; |
| |
| static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding ); |
| inline static bool IsWhiteSpace( char c ) |
| { |
| return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); |
| } |
| |
| virtual void StreamOut (TIXML_OSTREAM *) const = 0; |
| |
| #ifdef TIXML_USE_STL |
| static bool StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING * tag ); |
| static bool StreamTo( TIXML_ISTREAM * in, int character, TIXML_STRING * tag ); |
| #endif |
| |
| /* Reads an XML name into the string provided. Returns |
| a pointer just past the last character of the name, |
| or 0 if the function has an error. |
| */ |
| static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding ); |
| |
| /* Reads text. Returns a pointer past the given end tag. |
| Wickedly complex options, but it keeps the (sensitive) code in one place. |
| */ |
| static const char* ReadText( const char* in, // where to start |
| TIXML_STRING* text, // the string read |
| bool ignoreWhiteSpace, // whether to keep the white space |
| const char* endTag, // what ends this text |
| bool ignoreCase, // whether to ignore case in the end tag |
| TiXmlEncoding encoding ); // the current encoding |
| |
| // If an entity has been found, transform it into a character. |
| static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding ); |
| |
| // Get a character, while interpreting entities. |
| // The length can be from 0 to 4 bytes. |
| inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding ) |
| { |
| assert( p ); |
| if ( encoding == TIXML_ENCODING_UTF8 ) |
| { |
| *length = utf8ByteTable[ *((unsigned char*)p) ]; |
| assert( *length >= 0 && *length < 5 ); |
| } |
| else |
| { |
| *length = 1; |
| } |
| |
| if ( *length == 1 ) |
| { |
| if ( *p == '&' ) |
| return GetEntity( p, _value, length, encoding ); |
| *_value = *p; |
| return p+1; |
| } |
| else if ( *length ) |
| { |
| //strncpy( _value, p, *length ); // lots of compilers don't like this function (unsafe), |
| // and the null terminator isn't needed |
| for( int i=0; p[i] && i<*length; ++i ) { |
| _value[i] = p[i]; |
| } |
| return p + (*length); |
| } |
| else |
| { |
| // Not valid text. |
| return 0; |
| } |
| } |
| |
| // Puts a string to a stream, expanding entities as it goes. |
| // Note this should not contian the '<', '>', etc, or they will be transformed into entities! |
| static void PutString( const TIXML_STRING& str, TIXML_OSTREAM* out ); |
| |
| static void PutString( const TIXML_STRING& str, TIXML_STRING* out ); |
| |
| // Return true if the next characters in the stream are any of the endTag sequences. |
| // Ignore case only works for english, and should only be relied on when comparing |
| // to English words: StringEqual( p, "version", true ) is fine. |
| static bool StringEqual( const char* p, |
| const char* endTag, |
| bool ignoreCase, |
| TiXmlEncoding encoding ); |
| |
| static const char* errorString[ TIXML_ERROR_STRING_COUNT ]; |
| |
| TiXmlCursor location; |
| |
| /// Field containing a generic user pointer |
| void* userData; |
| |
| // None of these methods are reliable for any language except English. |
| // Good for approximation, not great for accuracy. |
| static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding ); |
| static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding ); |
| inline static int ToLower( int v, TiXmlEncoding encoding ) |
| { |
| if ( encoding == TIXML_ENCODING_UTF8 ) |
| { |
| if ( v < 128 ) return tolower( v ); |
| return v; |
| } |
| else |
| { |
| return tolower( v ); |
| } |
| } |
| static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ); |
| |
| private: |
| TiXmlBase( const TiXmlBase& ); // not implemented. |
| void operator=( const TiXmlBase& base ); // not allowed. |
| |
| struct Entity |
| { |
| const char* str; |
| unsigned int strLength; |
| char chr; |
| }; |
| enum |
| { |
| NUM_ENTITY = 5, |
| MAX_ENTITY_LENGTH = 6 |
| |
| }; |
| static Entity entity[ NUM_ENTITY ]; |
| static bool condenseWhiteSpace; |
| }; |
| |
| |
| /** The parent class for everything in the Document Object Model. |
| (Except for attributes). |
| Nodes have siblings, a parent, and children. A node can be |
| in a document, or stand on its own. The type of a TiXmlNode |
| can be queried, and it can be cast to its more defined type. |
| */ |
| class TiXmlNode : public TiXmlBase |
| { |
| friend class TiXmlDocument; |
| friend class TiXmlElement; |
| |
| public: |
| #ifdef TIXML_USE_STL |
| |
| /** An input stream operator, for every class. Tolerant of newlines and |
| formatting, but doesn't expect them. |
| */ |
| friend std::istream& operator >> (std::istream& in, TiXmlNode& base); |
| |
| /** An output stream operator, for every class. Note that this outputs |
| without any newlines or formatting, as opposed to Print(), which |
| includes tabs and new lines. |
| |
| The operator<< and operator>> are not completely symmetric. Writing |
| a node to a stream is very well defined. You'll get a nice stream |
| of output, without any extra whitespace or newlines. |
| |
| But reading is not as well defined. (As it always is.) If you create |
| a TiXmlElement (for example) and read that from an input stream, |
| the text needs to define an element or junk will result. This is |
| true of all input streams, but it's worth keeping in mind. |
| |
| A TiXmlDocument will read nodes until it reads a root element, and |
| all the children of that root element. |
| */ |
| friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base); |
| |
| /// Appends the XML node or attribute to a std::string. |
| friend std::string& operator<< (std::string& out, const TiXmlNode& base ); |
| |
| #else |
| // Used internally, not part of the public API. |
| friend TIXML_OSTREAM& operator<< (TIXML_OSTREAM& out, const TiXmlNode& base); |
| #endif |
| |
| /** The types of XML nodes supported by TinyXml. (All the |
| unsupported types are picked up by UNKNOWN.) |
| */ |
| enum NodeType |
| { |
| DOCUMENT, |
| ELEMENT, |
| COMMENT, |
| UNKNOWN, |
| TEXT, |
| DECLARATION, |
| TYPECOUNT |
| }; |
| |
| virtual ~TiXmlNode(); |
| |
| /** The meaning of 'value' changes for the specific type of |
| TiXmlNode. |
| @verbatim |
| Document: filename of the xml file |
| Element: name of the element |
| Comment: the comment text |
| Unknown: the tag contents |
| Text: the text string |
| @endverbatim |
| |
| The subclasses will wrap this function. |
| */ |
| const char *Value() const { return value.c_str (); } |
| |
| #ifdef TIXML_USE_STL |
| /** Return Value() as a std::string. If you only use STL, |
| this is more efficient than calling Value(). |
| Only available in STL mode. |
| */ |
| const std::string& ValueStr() const { return value; } |
| #endif |
| |
| /** Changes the value of the node. Defined as: |
| @verbatim |
| Document: filename of the xml file |
| Element: name of the element |
| Comment: the comment text |
| Unknown: the tag contents |
| Text: the text string |
| @endverbatim |
| */ |
| void SetValue(const char * _value) { value = _value;} |
| |
| #ifdef TIXML_USE_STL |
| /// STL std::string form. |
| void SetValue( const std::string& _value ) |
| { |
| StringToBuffer buf( _value ); |
| SetValue( buf.buffer ? buf.buffer : "" ); |
| } |
| #endif |
| |
| /// Delete all the children of this node. Does not affect 'this'. |
| void Clear(); |
| |
| /// One step up the DOM. |
| TiXmlNode* Parent() { return parent; } |
| const TiXmlNode* Parent() const { return parent; } |
| |
| const TiXmlNode* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children. |
| TiXmlNode* FirstChild() { return firstChild; } |
| const TiXmlNode* FirstChild( const char * value ) const; ///< The first child of this node with the matching 'value'. Will be null if none found. |
| TiXmlNode* FirstChild( const char * value ); ///< The first child of this node with the matching 'value'. Will be null if none found. |
| |
| const TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children. |
| TiXmlNode* LastChild() { return lastChild; } |
| const TiXmlNode* LastChild( const char * value ) const; /// The last child of this node matching 'value'. Will be null if there are no children. |
| TiXmlNode* LastChild( const char * value ); |
| |
| #ifdef TIXML_USE_STL |
| const TiXmlNode* FirstChild( const std::string& _value ) const { return FirstChild (_value.c_str ()); } ///< STL std::string form. |
| TiXmlNode* FirstChild( const std::string& _value ) { return FirstChild (_value.c_str ()); } ///< STL std::string form. |
| const TiXmlNode* LastChild( const std::string& _value ) const { return LastChild (_value.c_str ()); } ///< STL std::string form. |
| TiXmlNode* LastChild( const std::string& _value ) { return LastChild (_value.c_str ()); } ///< STL std::string form. |
| #endif |
| |
| /** An alternate way to walk the children of a node. |
| One way to iterate over nodes is: |
| @verbatim |
| for( child = parent->FirstChild(); child; child = child->NextSibling() ) |
| @endverbatim |
| |
| IterateChildren does the same thing with the syntax: |
| @verbatim |
| child = 0; |
| while( child = parent->IterateChildren( child ) ) |
| @endverbatim |
| |
| IterateChildren takes the previous child as input and finds |
| the next one. If the previous child is null, it returns the |
| first. IterateChildren will return null when done. |
| */ |
| const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const; |
| TiXmlNode* IterateChildren( TiXmlNode* previous ); |
| |
| /// This flavor of IterateChildren searches for children with a particular 'value' |
| const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const; |
| TiXmlNode* IterateChildren( const char * value, TiXmlNode* previous ); |
| |
| #ifdef TIXML_USE_STL |
| const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. |
| TiXmlNode* IterateChildren( const std::string& _value, TiXmlNode* previous ) { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. |
| #endif |
| |
| /** Add a new node related to this. Adds a child past the LastChild. |
| Returns a pointer to the new object or NULL if an error occured. |
| */ |
| TiXmlNode* InsertEndChild( const TiXmlNode& addThis ); |
| |
| |
| /** Add a new node related to this. Adds a child past the LastChild. |
| |
| NOTE: the node to be added is passed by pointer, and will be |
| henceforth owned (and deleted) by tinyXml. This method is efficient |
| and avoids an extra copy, but should be used with care as it |
| uses a different memory model than the other insert functions. |
| |
| @sa InsertEndChild |
| */ |
| TiXmlNode* LinkEndChild( TiXmlNode* addThis ); |
| |
| /** Add a new node related to this. Adds a child before the specified child. |
| Returns a pointer to the new object or NULL if an error occured. |
| */ |
| TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ); |
| |
| /** Add a new node related to this. Adds a child after the specified child. |
| Returns a pointer to the new object or NULL if an error occured. |
| */ |
| TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ); |
| |
| /** Replace a child of this node. |
| Returns a pointer to the new object or NULL if an error occured. |
| */ |
| TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ); |
| |
| /// Delete a child of this node. |
| bool RemoveChild( TiXmlNode* removeThis ); |
| |
| /// Navigate to a sibling node. |
| const TiXmlNode* PreviousSibling() const { return prev; } |
| TiXmlNode* PreviousSibling() { return prev; } |
| |
| /// Navigate to a sibling node. |
| const TiXmlNode* PreviousSibling( const char * ) const; |
| TiXmlNode* PreviousSibling( const char * ); |
| |
| #ifdef TIXML_USE_STL |
| const TiXmlNode* PreviousSibling( const std::string& _value ) const { return PreviousSibling (_value.c_str ()); } ///< STL std::string form. |
| TiXmlNode* PreviousSibling( const std::string& _value ) { return PreviousSibling (_value.c_str ()); } ///< STL std::string form. |
| const TiXmlNode* NextSibling( const std::string& _value) const { return NextSibling (_value.c_str ()); } ///< STL std::string form. |
| TiXmlNode* NextSibling( const std::string& _value) { return NextSibling (_value.c_str ()); } ///< STL std::string form. |
| #endif |
| |
| /// Navigate to a sibling node. |
| const TiXmlNode* NextSibling() const { return next; } |
| TiXmlNode* NextSibling() { return next; } |
| |
| /// Navigate to a sibling node with the given 'value'. |
| const TiXmlNode* NextSibling( const char * ) const; |
| TiXmlNode* NextSibling( const char * ); |
| |
| /** Convenience function to get through elements. |
| Calls NextSibling and ToElement. Will skip all non-Element |
| nodes. Returns 0 if there is not another element. |
| */ |
| const TiXmlElement* NextSiblingElement() const; |
| TiXmlElement* NextSiblingElement(); |
| |
| /** Convenience function to get through elements. |
| Calls NextSibling and ToElement. Will skip all non-Element |
| nodes. Returns 0 if there is not another element. |
| */ |
| const TiXmlElement* NextSiblingElement( const char * ) const; |
| TiXmlElement* NextSiblingElement( const char * ); |
| |
| #ifdef TIXML_USE_STL |
| const TiXmlElement* NextSiblingElement( const std::string& _value) const { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form. |
| TiXmlElement* NextSiblingElement( const std::string& _value) { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form. |
| #endif |
| |
| /// Convenience function to get through elements. |
| const TiXmlElement* FirstChildElement() const; |
| TiXmlElement* FirstChildElement(); |
| |
| /// Convenience function to get through elements. |
| const TiXmlElement* FirstChildElement( const char * value ) const; |
| TiXmlElement* FirstChildElement( const char * value ); |
| |
| #ifdef TIXML_USE_STL |
| const TiXmlElement* FirstChildElement( const std::string& _value ) const { return FirstChildElement (_value.c_str ()); } ///< STL std::string form. |
| TiXmlElement* FirstChildElement( const std::string& _value ) { return FirstChildElement (_value.c_str ()); } ///< STL std::string form. |
| #endif |
| |
| /** Query the type (as an enumerated value, above) of this node. |
| The possible types are: DOCUMENT, ELEMENT, COMMENT, |
| UNKNOWN, TEXT, and DECLARATION. |
| */ |
| virtual int Type() const { return type; } |
| |
| /** Return a pointer to the Document this node lives in. |
| Returns null if not in a document. |
| */ |
| const TiXmlDocument* GetDocument() const; |
| TiXmlDocument* GetDocument(); |
| |
| /// Returns true if this node has no children. |
| bool NoChildren() const { return !firstChild; } |
| |
| const TiXmlDocument* ToDocument() const { return ( this && type == DOCUMENT ) ? (const TiXmlDocument*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. |
| const TiXmlElement* ToElement() const { return ( this && type == ELEMENT ) ? (const TiXmlElement*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. |
| const TiXmlComment* ToComment() const { return ( this && type == COMMENT ) ? (const TiXmlComment*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. |
| const TiXmlUnknown* ToUnknown() const { return ( this && type == UNKNOWN ) ? (const TiXmlUnknown*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. |
| const TiXmlText* ToText() const { return ( this && type == TEXT ) ? (const TiXmlText*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. |
| const TiXmlDeclaration* ToDeclaration() const { return ( this && type == DECLARATION ) ? (const TiXmlDeclaration*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. |
| |
| TiXmlDocument* ToDocument() { return ( this && type == DOCUMENT ) ? (TiXmlDocument*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. |
| TiXmlElement* ToElement() { return ( this && type == ELEMENT ) ? (TiXmlElement*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. |
| TiXmlComment* ToComment() { return ( this && type == COMMENT ) ? (TiXmlComment*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. |
| TiXmlUnknown* ToUnknown() { return ( this && type == UNKNOWN ) ? (TiXmlUnknown*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. |
| TiXmlText* ToText() { return ( this && type == TEXT ) ? (TiXmlText*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. |
| TiXmlDeclaration* ToDeclaration() { return ( this && type == DECLARATION ) ? (TiXmlDeclaration*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type. |
| |
| /** Create an exact duplicate of this node and return it. The memory must be deleted |
| by the caller. |
| */ |
| virtual TiXmlNode* Clone() const = 0; |
| |
| protected: |
| TiXmlNode( NodeType _type ); |
| |
| // Copy to the allocated object. Shared functionality between Clone, Copy constructor, |
| // and the assignment operator. |
| void CopyTo( TiXmlNode* target ) const; |
| |
| #ifdef TIXML_USE_STL |
| // The real work of the input operator. |
| virtual void StreamIn( TIXML_ISTREAM* in, TIXML_STRING* tag ) = 0; |
| #endif |
| |
| // Figure out what is at *p, and parse it. Returns null if it is not an xml node. |
| TiXmlNode* Identify( const char* start, TiXmlEncoding encoding ); |
| |
| TiXmlNode* parent; |
| NodeType type; |
| |
| TiXmlNode* firstChild; |
| TiXmlNode* lastChild; |
| |
| TIXML_STRING value; |
| |
| TiXmlNode* prev; |
| TiXmlNode* next; |
| |
| private: |
| TiXmlNode( const TiXmlNode& ); // not implemented. |
| void operator=( const TiXmlNode& base ); // not allowed. |
| }; |
| |
| |
| /** An attribute is a name-value pair. Elements have an arbitrary |
| number of attributes, each with a unique name. |
| |
| @note The attributes are not TiXmlNodes, since they are not |
| part of the tinyXML document object model. There are other |
| suggested ways to look at this problem. |
| */ |
| class TiXmlAttribute : public TiXmlBase |
| { |
| friend class TiXmlAttributeSet; |
| |
| public: |
| /// Construct an empty attribute. |
| TiXmlAttribute() : TiXmlBase() |
| { |
| document = 0; |
| prev = next = 0; |
| } |
| |
| #ifdef TIXML_USE_STL |
| /// std::string constructor. |
| TiXmlAttribute( const std::string& _name, const std::string& _value ) |
| { |
| name = _name; |
| value = _value; |
| document = 0; |
| prev = next = 0; |
| } |
| #endif |
| |
| /// Construct an attribute with a name and value. |
| TiXmlAttribute( const char * _name, const char * _value ) |
| { |
| name = _name; |
| value = _value; |
| document = 0; |
| prev = next = 0; |
| } |
| |
| const char* Name() const { return name.c_str (); } ///< Return the name of this attribute. |
| const char* Value() const { return value.c_str (); } ///< Return the value of this attribute. |
| int IntValue() const; ///< Return the value of this attribute, converted to an integer. |
| double DoubleValue() const; ///< Return the value of this attribute, converted to a double. |
| |
| /** QueryIntValue examines the value string. It is an alternative to the |
| IntValue() method with richer error checking. |
| If the value is an integer, it is stored in 'value' and |
| the call returns TIXML_SUCCESS. If it is not |
| an integer, it returns TIXML_WRONG_TYPE. |
| |
| A specialized but useful call. Note that for success it returns 0, |
| which is the opposite of almost all other TinyXml calls. |
| */ |
| int QueryIntValue( int* _value ) const; |
| /// QueryDoubleValue examines the value string. See QueryIntValue(). |
| int QueryDoubleValue( double* _value ) const; |
| |
| void SetName( const char* _name ) { name = _name; } ///< Set the name of this attribute. |
| void SetValue( const char* _value ) { value = _value; } ///< Set the value. |
| |
| void SetIntValue( int _value ); ///< Set the value from an integer. |
| void SetDoubleValue( double _value ); ///< Set the value from a double. |
| |
| #ifdef TIXML_USE_STL |
| /// STL std::string form. |
| void SetName( const std::string& _name ) |
| { |
| StringToBuffer buf( _name ); |
| SetName ( buf.buffer ? buf.buffer : "error" ); |
| } |
| /// STL std::string form. |
| void SetValue( const std::string& _value ) |
| { |
| StringToBuffer buf( _value ); |
| SetValue( buf.buffer ? buf.buffer : "error" ); |
| } |
| #endif |
| |
| /// Get the next sibling attribute in the DOM. Returns null at end. |
| const TiXmlAttribute* Next() const; |
| TiXmlAttribute* Next(); |
| /// Get the previous sibling attribute in the DOM. Returns null at beginning. |
| const TiXmlAttribute* Previous() const; |
| TiXmlAttribute* Previous(); |
| |
| bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; } |
| bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; } |
| bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; } |
| |
| /* Attribute parsing starts: first letter of the name |
| returns: the next char after the value end quote |
| */ |
| virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); |
| |
| // Prints this Attribute to a FILE stream. |
| virtual void Print( FILE* cfile, int depth ) const; |
| |
| virtual void StreamOut( TIXML_OSTREAM * out ) const; |
| // [internal use] |
| // Set the document pointer so the attribute can report errors. |
| void SetDocument( TiXmlDocument* doc ) { document = doc; } |
| |
| private: |
| TiXmlAttribute( const TiXmlAttribute& ); // not implemented. |
| void operator=( const TiXmlAttribute& base ); // not allowed. |
| |
| TiXmlDocument* document; // A pointer back to a document, for error reporting. |
| TIXML_STRING name; |
| TIXML_STRING value; |
| TiXmlAttribute* prev; |
| TiXmlAttribute* next; |
| }; |
| |
| |
| /* A class used to manage a group of attributes. |
| It is only used internally, both by the ELEMENT and the DECLARATION. |
| |
| The set can be changed transparent to the Element and Declaration |
| classes that use it, but NOT transparent to the Attribute |
| which has to implement a next() and previous() method. Which makes |
| it a bit problematic and prevents the use of STL. |
| |
| This version is implemented with circular lists because: |
| - I like circular lists |
| - it demonstrates some independence from the (typical) doubly linked list. |
| */ |
| class TiXmlAttributeSet |
| { |
| public: |
| TiXmlAttributeSet(); |
| ~TiXmlAttributeSet(); |
| |
| void Add( TiXmlAttribute* attribute ); |
| void Remove( TiXmlAttribute* attribute ); |
| |
| const TiXmlAttribute* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } |
| TiXmlAttribute* First() { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } |
| const TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } |
| TiXmlAttribute* Last() { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } |
| |
| const TiXmlAttribute* Find( const char * name ) const; |
| TiXmlAttribute* Find( const char * name ); |
| |
| private: |
| //*ME: Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element), |
| //*ME: this class must be also use a hidden/disabled copy-constructor !!! |
| TiXmlAttributeSet( const TiXmlAttributeSet& ); // not allowed |
| void operator=( const TiXmlAttributeSet& ); // not allowed (as TiXmlAttribute) |
| |
| TiXmlAttribute sentinel; |
| }; |
| |
| |
| /** The element is a container class. It has a value, the element name, |
| and can contain other elements, text, comments, and unknowns. |
| Elements also contain an arbitrary number of attributes. |
| */ |
| class TiXmlElement : public TiXmlNode |
| { |
| public: |
| /// Construct an element. |
| TiXmlElement (const char * in_value); |
| |
| #ifdef TIXML_USE_STL |
| /// std::string constructor. |
| TiXmlElement( const std::string& _value ); |
| #endif |
| |
| TiXmlElement( const TiXmlElement& ); |
| |
| void operator=( const TiXmlElement& base ); |
| |
| virtual ~TiXmlElement(); |
| |
| /** Given an attribute name, Attribute() returns the value |
| for the attribute of that name, or null if none exists. |
| */ |
| const char* Attribute( const char* name ) const; |
| |
| /** Given an attribute name, Attribute() returns the value |
| for the attribute of that name, or null if none exists. |
| If the attribute exists and can be converted to an integer, |
| the integer value will be put in the return 'i', if 'i' |
| is non-null. |
| */ |
| const char* Attribute( const char* name, int* i ) const; |
| |
| /** Given an attribute name, Attribute() returns the value |
| for the attribute of that name, or null if none exists. |
| If the attribute exists and can be converted to an double, |
| the double value will be put in the return 'd', if 'd' |
| is non-null. |
| */ |
| const char* Attribute( const char* name, double* d ) const; |
| |
| /** QueryIntAttribute examines the attribute - it is an alternative to the |
| Attribute() method with richer error checking. |
| If the attribute is an integer, it is stored in 'value' and |
| the call returns TIXML_SUCCESS. If it is not |
| an integer, it returns TIXML_WRONG_TYPE. If the attribute |
| does not exist, then TIXML_NO_ATTRIBUTE is returned. |
| */ |
| int QueryIntAttribute( const char* name, int* _value ) const; |
| /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute(). |
| int QueryDoubleAttribute( const char* name, double* _value ) const; |
| /// QueryFloatAttribute examines the attribute - see QueryIntAttribute(). |
| int QueryFloatAttribute( const char* name, float* _value ) const { |
| double d; |
| int result = QueryDoubleAttribute( name, &d ); |
| if ( result == TIXML_SUCCESS ) { |
| *_value = (float)d; |
| } |
| return result; |
| } |
| |
| /** Sets an attribute of name to a given value. The attribute |
| will be created if it does not exist, or changed if it does. |
| */ |
| void SetAttribute( const char* name, const char * _value ); |
| |
| #ifdef TIXML_USE_STL |
| const char* Attribute( const std::string& name ) const { return Attribute( name.c_str() ); } |
| const char* Attribute( const std::string& name, int* i ) const { return Attribute( name.c_str(), i ); } |
| const char* Attribute( const std::string& name, double* d ) const { return Attribute( name.c_str(), d ); } |
| int QueryIntAttribute( const std::string& name, int* _value ) const { return QueryIntAttribute( name.c_str(), _value ); } |
| int QueryDoubleAttribute( const std::string& name, double* _value ) const { return QueryDoubleAttribute( name.c_str(), _value ); } |
| |
| /// STL std::string form. |
| void SetAttribute( const std::string& name, const std::string& _value ) |
| { |
| StringToBuffer n( name ); |
| StringToBuffer v( _value ); |
| if ( n.buffer && v.buffer ) |
| SetAttribute (n.buffer, v.buffer ); |
| } |
| ///< STL std::string form. |
| void SetAttribute( const std::string& name, int _value ) |
| { |
| StringToBuffer n( name ); |
| if ( n.buffer ) |
| SetAttribute (n.buffer, _value); |
| } |
| #endif |
| |
| /** Sets an attribute of name to a given value. The attribute |
| will be created if it does not exist, or changed if it does. |
| */ |
| void SetAttribute( const char * name, int value ); |
| |
| /** Sets an attribute of name to a given value. The attribute |
| will be created if it does not exist, or changed if it does. |
| */ |
| void SetDoubleAttribute( const char * name, double value ); |
| |
| /** Deletes an attribute with the given name. |
| */ |
| void RemoveAttribute( const char * name ); |
| #ifdef TIXML_USE_STL |
| void RemoveAttribute( const std::string& name ) { RemoveAttribute (name.c_str ()); } ///< STL std::string form. |
| #endif |
| |
| const TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); } ///< Access the first attribute in this element. |
| TiXmlAttribute* FirstAttribute() { return attributeSet.First(); } |
| const TiXmlAttribute* LastAttribute() const { return attributeSet.Last(); } ///< Access the last attribute in this element. |
| TiXmlAttribute* LastAttribute() { return attributeSet.Last(); } |
| |
| /** Convenience function for easy access to the text inside an element. Although easy |
| and concise, GetText() is limited compared to getting the TiXmlText child |
| and accessing it directly. |
| |
| If the first child of 'this' is a TiXmlText, the GetText() |
| returs the character string of the Text node, else null is returned. |
| |
| This is a convenient method for getting the text of simple contained text: |
| @verbatim |
| <foo>This is text</foo> |
| const char* str = fooElement->GetText(); |
| @endverbatim |
| |
| 'str' will be a pointer to "This is text". |
| |
| Note that this function can be misleading. If the element foo was created from |
| this XML: |
| @verbatim |
| <foo><b>This is text</b></foo> |
| @endverbatim |
| |
| then the value of str would be null. The first child node isn't a text node, it is |
| another element. From this XML: |
| @verbatim |
| <foo>This is <b>text</b></foo> |
| @endverbatim |
| GetText() will return "This is ". |
| |
| WARNING: GetText() accesses a child node - don't become confused with the |
| similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are |
| safe type casts on the referenced node. |
| */ |
| const char* GetText() const; |
| |
| /// Creates a new Element and returns it - the returned element is a copy. |
| virtual TiXmlNode* Clone() const; |
| // Print the Element to a FILE stream. |
| virtual void Print( FILE* cfile, int depth ) const; |
| |
| /* Attribtue parsing starts: next char past '<' |
| returns: next char past '>' |
| */ |
| virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); |
| |
| protected: |
| |
| void CopyTo( TiXmlElement* target ) const; |
| void ClearThis(); // like clear, but initializes 'this' object as well |
| |
| // Used to be public [internal use] |
| #ifdef TIXML_USE_STL |
| virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); |
| #endif |
| virtual void StreamOut( TIXML_OSTREAM * out ) const; |
| |
| /* [internal use] |
| Reads the "value" of the element -- another element, or text. |
| This should terminate with the current end tag. |
| */ |
| const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding ); |
| |
| private: |
| |
| TiXmlAttributeSet attributeSet; |
| }; |
| |
| |
| /** An XML comment. |
| */ |
| class TiXmlComment : public TiXmlNode |
| { |
| public: |
| /// Constructs an empty comment. |
| TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {} |
| TiXmlComment( const TiXmlComment& ); |
| void operator=( const TiXmlComment& base ); |
| |
| virtual ~TiXmlComment() {} |
| |
| /// Returns a copy of this Comment. |
| virtual TiXmlNode* Clone() const; |
| /// Write this Comment to a FILE stream. |
| virtual void Print( FILE* cfile, int depth ) const; |
| |
| /* Attribtue parsing starts: at the ! of the !-- |
| returns: next char past '>' |
| */ |
| virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); |
| |
| protected: |
| void CopyTo( TiXmlComment* target ) const; |
| |
| // used to be public |
| #ifdef TIXML_USE_STL |
| virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); |
| #endif |
| virtual void StreamOut( TIXML_OSTREAM * out ) const; |
| |
| private: |
| |
| }; |
| |
| |
| /** XML text. A text node can have 2 ways to output the next. "normal" output |
| and CDATA. It will default to the mode it was parsed from the XML file and |
| you generally want to leave it alone, but you can change the output mode with |
| SetCDATA() and query it with CDATA(). |
| */ |
| class TiXmlText : public TiXmlNode |
| { |
| friend class TiXmlElement; |
| public: |
| /** Constructor for text element. By default, it is treated as |
| normal, encoded text. If you want it be output as a CDATA text |
| element, set the parameter _cdata to 'true' |
| */ |
| TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TEXT) |
| { |
| SetValue( initValue ); |
| cdata = false; |
| } |
| virtual ~TiXmlText() {} |
| |
| #ifdef TIXML_USE_STL |
| /// Constructor. |
| TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT) |
| { |
| SetValue( initValue ); |
| cdata = false; |
| } |
| #endif |
| |
| TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT ) { copy.CopyTo( this ); } |
| void operator=( const TiXmlText& base ) { base.CopyTo( this ); } |
| |
| /// Write this text object to a FILE stream. |
| virtual void Print( FILE* cfile, int depth ) const; |
| |
| /// Queries whether this represents text using a CDATA section. |
| bool CDATA() { return cdata; } |
| /// Turns on or off a CDATA representation of text. |
| void SetCDATA( bool _cdata ) { cdata = _cdata; } |
| |
| virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); |
| |
| protected : |
| /// [internal use] Creates a new Element and returns it. |
| virtual TiXmlNode* Clone() const; |
| void CopyTo( TiXmlText* target ) const; |
| |
| virtual void StreamOut ( TIXML_OSTREAM * out ) const; |
| bool Blank() const; // returns true if all white space and new lines |
| // [internal use] |
| #ifdef TIXML_USE_STL |
| virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); |
| #endif |
| |
| private: |
| bool cdata; // true if this should be input and output as a CDATA style text element |
| }; |
| |
| |
| /** In correct XML the declaration is the first entry in the file. |
| @verbatim |
| <?xml version="1.0" standalone="yes"?> |
| @endverbatim |
| |
| TinyXml will happily read or write files without a declaration, |
| however. There are 3 possible attributes to the declaration: |
| version, encoding, and standalone. |
| |
| Note: In this version of the code, the attributes are |
| handled as special cases, not generic attributes, simply |
| because there can only be at most 3 and they are always the same. |
| */ |
| class TiXmlDeclaration : public TiXmlNode |
| { |
| public: |
| /// Construct an empty declaration. |
| TiXmlDeclaration() : TiXmlNode( TiXmlNode::DECLARATION ) {} |
| |
| #ifdef TIXML_USE_STL |
| /// Constructor. |
| TiXmlDeclaration( const std::string& _version, |
| const std::string& _encoding, |
| const std::string& _standalone ); |
| #endif |
| |
| /// Construct. |
| TiXmlDeclaration( const char* _version, |
| const char* _encoding, |
| const char* _standalone ); |
| |
| TiXmlDeclaration( const TiXmlDeclaration& copy ); |
| void operator=( const TiXmlDeclaration& copy ); |
| |
| virtual ~TiXmlDeclaration() {} |
| |
| /// Version. Will return an empty string if none was found. |
| const char *Version() const { return version.c_str (); } |
| /// Encoding. Will return an empty string if none was found. |
| const char *Encoding() const { return encoding.c_str (); } |
| /// Is this a standalone document? |
| const char *Standalone() const { return standalone.c_str (); } |
| |
| /// Creates a copy of this Declaration and returns it. |
| virtual TiXmlNode* Clone() const; |
| /// Print this declaration to a FILE stream. |
| virtual void Print( FILE* cfile, int depth ) const; |
| |
| virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); |
| |
| protected: |
| void CopyTo( TiXmlDeclaration* target ) const; |
| // used to be public |
| #ifdef TIXML_USE_STL |
| virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); |
| #endif |
| virtual void StreamOut ( TIXML_OSTREAM * out) const; |
| |
| private: |
| |
| TIXML_STRING version; |
| TIXML_STRING encoding; |
| TIXML_STRING standalone; |
| }; |
| |
| |
| /** Any tag that tinyXml doesn't recognize is saved as an |
| unknown. It is a tag of text, but should not be modified. |
| It will be written back to the XML, unchanged, when the file |
| is saved. |
| |
| DTD tags get thrown into TiXmlUnknowns. |
| */ |
| class TiXmlUnknown : public TiXmlNode |
| { |
| public: |
| TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN ) {} |
| virtual ~TiXmlUnknown() {} |
| |
| TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN ) { copy.CopyTo( this ); } |
| void operator=( const TiXmlUnknown& copy ) { copy.CopyTo( this ); } |
| |
| /// Creates a copy of this Unknown and returns it. |
| virtual TiXmlNode* Clone() const; |
| /// Print this Unknown to a FILE stream. |
| virtual void Print( FILE* cfile, int depth ) const; |
| |
| virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); |
| |
| protected: |
| void CopyTo( TiXmlUnknown* target ) const; |
| |
| #ifdef TIXML_USE_STL |
| virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); |
| #endif |
| virtual void StreamOut ( TIXML_OSTREAM * out ) const; |
| |
| private: |
| |
| }; |
| |
| |
| /** Always the top level node. A document binds together all the |
| XML pieces. It can be saved, loaded, and printed to the screen. |
| The 'value' of a document node is the xml file name. |
| */ |
| class TiXmlDocument : public TiXmlNode |
| { |
| public: |
| /// Create an empty document, that has no name. |
| TiXmlDocument(); |
| /// Create a document with a name. The name of the document is also the filename of the xml. |
| TiXmlDocument( const char * documentName ); |
| |
| #ifdef TIXML_USE_STL |
| /// Constructor. |
| TiXmlDocument( const std::string& documentName ); |
| #endif |
| |
| TiXmlDocument( const TiXmlDocument& copy ); |
| void operator=( const TiXmlDocument& copy ); |
| |
| virtual ~TiXmlDocument() {} |
| |
| /** Load a file using the current document value. |
| Returns true if successful. Will delete any existing |
| document data before loading. |
| */ |
| bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); |
| /// Save a file using the current document value. Returns true if successful. |
| bool SaveFile() const; |
| /// Load a file using the given filename. Returns true if successful. |
| bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); |
| /// Save a file using the given filename. Returns true if successful. |
| bool SaveFile( const char * filename ) const; |
| |
| #ifdef TIXML_USE_STL |
| bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ) ///< STL std::string version. |
| { |
| StringToBuffer f( filename ); |
| return ( f.buffer && LoadFile( f.buffer, encoding )); |
| } |
| bool SaveFile( const std::string& filename ) const ///< STL std::string version. |
| { |
| StringToBuffer f( filename ); |
| return ( f.buffer && SaveFile( f.buffer )); |
| } |
| #endif |
| |
| /** Parse the given null terminated block of xml data. Passing in an encoding to this |
| method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml |
| to use that encoding, regardless of what TinyXml might otherwise try to detect. |
| */ |
| virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); |
| |
| /** Get the root element -- the only top level element -- of the document. |
| In well formed XML, there should only be one. TinyXml is tolerant of |
| multiple elements at the document level. |
| */ |
| const TiXmlElement* RootElement() const { return FirstChildElement(); } |
| TiXmlElement* RootElement() { return FirstChildElement(); } |
| |
| /** If an error occurs, Error will be set to true. Also, |
| - The ErrorId() will contain the integer identifier of the error (not generally useful) |
| - The ErrorDesc() method will return the name of the error. (very useful) |
| - The ErrorRow() and ErrorCol() will return the location of the error (if known) |
| */ |
| bool Error() const { return error; } |
| |
| /// Contains a textual (english) description of the error if one occurs. |
| const char * ErrorDesc() const { return errorDesc.c_str (); } |
| |
| /** Generally, you probably want the error string ( ErrorDesc() ). But if you |
| prefer the ErrorId, this function will fetch it. |
| */ |
| int ErrorId() const { return errorId; } |
| |
| /** Returns the location (if known) of the error. The first column is column 1, |
| and the first row is row 1. A value of 0 means the row and column wasn't applicable |
| (memory errors, for example, have no row/column) or the parser lost the error. (An |
| error in the error reporting, in that case.) |
| |
| @sa SetTabSize, Row, Column |
| */ |
| int ErrorRow() { return errorLocation.row+1; } |
| int ErrorCol() { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow() |
| |
| /** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol()) |
| to report the correct values for row and column. It does not change the output |
| or input in any way. |
| |
| By calling this method, with a tab size |
| greater than 0, the row and column of each node and attribute is stored |
| when the file is loaded. Very useful for tracking the DOM back in to |
| the source file. |
| |
| The tab size is required for calculating the location of nodes. If not |
| set, the default of 4 is used. The tabsize is set per document. Setting |
| the tabsize to 0 disables row/column tracking. |
| |
| Note that row and column tracking is not supported when using operator>>. |
| |
| The tab size needs to be enabled before the parse or load. Correct usage: |
| @verbatim |
| TiXmlDocument doc; |
| doc.SetTabSize( 8 ); |
| doc.Load( "myfile.xml" ); |
| @endverbatim |
| |
| @sa Row, Column |
| */ |
| void SetTabSize( int _tabsize ) { tabsize = _tabsize; } |
| |
| int TabSize() const { return tabsize; } |
| |
| /** If you have handled the error, it can be reset with this call. The error |
| state is automatically cleared if you Parse a new XML block. |
| */ |
| void ClearError() { error = false; |
| errorId = 0; |
| errorDesc = ""; |
| errorLocation.row = errorLocation.col = 0; |
| //errorLocation.last = 0; |
| } |
| |
| /** Dump the document to standard out. */ |
| void Print() const { Print( stdout, 0 ); } |
| |
| /// Print this Document to a FILE stream. |
| virtual void Print( FILE* cfile, int depth = 0 ) const; |
| // [internal use] |
| void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding ); |
| |
| protected : |
| virtual void StreamOut ( TIXML_OSTREAM * out) const; |
| // [internal use] |
| virtual TiXmlNode* Clone() const; |
| #ifdef TIXML_USE_STL |
| virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ); |
| #endif |
| |
| private: |
| void CopyTo( TiXmlDocument* target ) const; |
| |
| bool error; |
| int errorId; |
| TIXML_STRING errorDesc; |
| int tabsize; |
| TiXmlCursor errorLocation; |
| bool useMicrosoftBOM; // the UTF-8 BOM were found when read. Note this, and try to write. |
| }; |
| |
| |
| /** |
| A TiXmlHandle is a class that wraps a node pointer with null checks; this is |
| an incredibly useful thing. Note that TiXmlHandle 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 |
| 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 ).Element(); |
| 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 |
| |
| What they should not be used for is iteration: |
| |
| @verbatim |
| int i=0; |
| while ( true ) |
| { |
| TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).Element(); |
| if ( !child ) |
| break; |
| // do something |
| ++i; |
| } |
| @endverbatim |
| |
| It seems reasonable, but it is in fact two embedded while loops. The Child method is |
| a linear walk to find the element, so this code would iterate much more than it needs |
| to. Instead, prefer: |
| |
| @verbatim |
| TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).Element(); |
| |
| for( child; child; child=child->NextSiblingElement() ) |
| { |
| // do something |
| } |
| @endverbatim |
| */ |
| class TiXmlHandle |
| { |
| public: |
| /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. |
| TiXmlHandle( TiXmlNode* _node ) { this->node = _node; } |
| /// Copy constructor |
| TiXmlHandle( const TiXmlHandle& ref ) { this->node = ref.node; } |
| TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; } |
| |
| /// Return a handle to the first child node. |
| TiXmlHandle FirstChild() const; |
| /// Return a handle to the first child node with the given name. |
| TiXmlHandle FirstChild( const char * value ) const; |
| /// Return a handle to the first child element. |
| TiXmlHandle FirstChildElement() const; |
| /// Return a handle to the first child element with the given name. |
| TiXmlHandle FirstChildElement( const char * value ) const; |
| |
| /** Return a handle to the "index" child with the given name. |
| The first child is 0, the second 1, etc. |
| */ |
| TiXmlHandle Child( const char* value, int index ) const; |
| /** Return a handle to the "index" child. |
| The first child is 0, the second 1, etc. |
| */ |
| TiXmlHandle Child( int index ) const; |
| /** Return a handle to the "index" child element with the given name. |
| The first child element is 0, the second 1, etc. Note that only TiXmlElements |
| are indexed: other types are not counted. |
| */ |
| TiXmlHandle ChildElement( const char* value, int index ) const; |
| /** Return a handle to the "index" child element. |
| The first child element is 0, the second 1, etc. Note that only TiXmlElements |
| are indexed: other types are not counted. |
| */ |
| TiXmlHandle ChildElement( int index ) const; |
| |
| #ifdef TIXML_USE_STL |
| TiXmlHandle FirstChild( const std::string& _value ) const { return FirstChild( _value.c_str() ); } |
| TiXmlHandle FirstChildElement( const std::string& _value ) const { return FirstChildElement( _value.c_str() ); } |
| |
| TiXmlHandle Child( const std::string& _value, int index ) const { return Child( _value.c_str(), index ); } |
| TiXmlHandle ChildElement( const std::string& _value, int index ) const { return ChildElement( _value.c_str(), index ); } |
| #endif |
| |
| /// Return the handle as a TiXmlNode. This may return null. |
| TiXmlNode* Node() const { return node; } |
| /// Return the handle as a TiXmlElement. This may return null. |
| TiXmlElement* Element() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } |
| /// Return the handle as a TiXmlText. This may return null. |
| TiXmlText* Text() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); } |
| /// Return the handle as a TiXmlUnknown. This may return null; |
| TiXmlUnknown* Unknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); } |
| |
| private: |
| TiXmlNode* node; |
| }; |
| |
| #ifdef _MSC_VER |
| #pragma warning( pop ) |
| #endif |
| |
| #endif |
| |