2 www.sourceforge.net/projects/tinyxml
3 Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any
7 damages arising from the use of this software.
9 Permission is granted to anyone to use this software for any
10 purpose, including commercial applications, and to alter it and
11 redistribute it freely, subject to the following restrictions:
13 1. The origin of this software must not be misrepresented; you must
14 not claim that you wrote the original software. If you use this
15 software in a product, an acknowledgment in the product documentation
16 would be appreciated but is not required.
18 2. Altered source versions must be plainly marked as such, and
19 must not be misrepresented as being the original software.
21 3. This notice may not be removed or altered from any source
26 #ifndef TINYXML_INCLUDED
27 #define TINYXML_INCLUDED
30 #pragma warning( push )
31 #pragma warning( disable : 4530 )
32 #pragma warning( disable : 4786 )
42 #if defined( _DEBUG ) && !defined( DEBUG )
50 #define TIXML_STRING std::string
53 #define TIXML_STRING TiXmlString
56 #include <tinyxml/cpPlugins_tinyxml_Export.h>
58 // Deprecated library function hell. Compilers want to use the
59 // new safe versions. This probably doesn't fully address the problem,
60 // but it gets closer. There are too many compilers for me to fully
61 // test. If you get compilation troubles, undefine TIXML_SAFE
65 #if defined(_MSC_VER) && (_MSC_VER >= 1400 )
66 // Microsoft visual studio, version 2005 and higher.
67 #define TIXML_SNPRINTF _snprintf_s
68 #define TIXML_SSCANF sscanf_s
69 #elif defined(_MSC_VER) && (_MSC_VER >= 1200 )
70 // Microsoft visual studio, version 6 and higher.
71 //#pragma message( "Using _sn* functions." )
72 #define TIXML_SNPRINTF _snprintf
73 #define TIXML_SSCANF sscanf
74 #elif defined(__GNUC__) && (__GNUC__ >= 3 )
75 // GCC version 3 and higher.s
76 //#warning( "Using sn* functions." )
77 #define TIXML_SNPRINTF snprintf
78 #define TIXML_SSCANF sscanf
80 #define TIXML_SNPRINTF snprintf
81 #define TIXML_SSCANF sscanf
91 class TiXmlDeclaration;
92 class TiXmlParsingData;
94 const int TIXML_MAJOR_VERSION = 2;
95 const int TIXML_MINOR_VERSION = 6;
96 const int TIXML_PATCH_VERSION = 1;
98 /* Internal structure for tracking location of items
101 struct cpPlugins_tinyxml_EXPORT TiXmlCursor
103 TiXmlCursor() { Clear(); }
104 void Clear() { row = col = -1; }
112 Implements the interface to the "Visitor pattern" (see the Accept() method.)
113 If you call the Accept() method, it requires being passed a TiXmlVisitor
114 class to handle callbacks. For nodes that contain other nodes (Document, Element)
115 you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves
116 are simply called with Visit().
118 If you return 'true' from a Visit method, recursive parsing will continue. If you return
119 false, <b>no children of this node or its sibilings</b> will be Visited.
121 All flavors of Visit methods have a default implementation that returns 'true' (continue
122 visiting). You need to only override methods that are interesting to you.
124 Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting.
126 You should never change the document from a callback.
128 @sa TiXmlNode::Accept()
133 virtual ~TiXmlVisitor() {}
135 /// Visit a document.
136 virtual bool VisitEnter( const TiXmlDocument& /*doc*/ ) { return true; }
137 /// Visit a document.
138 virtual bool VisitExit( const TiXmlDocument& /*doc*/ ) { return true; }
140 /// Visit an element.
141 virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ ) { return true; }
142 /// Visit an element.
143 virtual bool VisitExit( const TiXmlElement& /*element*/ ) { return true; }
145 /// Visit a declaration
146 virtual bool Visit( const TiXmlDeclaration& /*declaration*/ ) { return true; }
147 /// Visit a text node
148 virtual bool Visit( const TiXmlText& /*text*/ ) { return true; }
149 /// Visit a comment node
150 virtual bool Visit( const TiXmlComment& /*comment*/ ) { return true; }
151 /// Visit an unknow node
152 virtual bool Visit( const TiXmlUnknown& /*unknown*/ ) { return true; }
155 // Only used by Attribute::Query functions
164 // Used by the parsing routines.
167 TIXML_ENCODING_UNKNOWN,
169 TIXML_ENCODING_LEGACY
172 const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN;
174 /** TiXmlBase is a base class for every class in TinyXml.
175 It does little except to establish that TinyXml classes
176 can be printed and provide some utility functions.
178 In XML, the document and elements can contain
179 other elements and other types of nodes.
182 A Document can contain: Element (container or leaf)
187 An Element can contain: Element (container or leaf)
189 Attributes (not on tree)
193 A Decleration contains: Attributes (not on tree)
196 class cpPlugins_tinyxml_EXPORT TiXmlBase
198 friend class TiXmlNode;
199 friend class TiXmlElement;
200 friend class TiXmlDocument;
203 TiXmlBase() : userData(0) {}
204 virtual ~TiXmlBase() {}
206 /** All TinyXml classes can print themselves to a filestream
207 or the string class (TiXmlString in non-STL mode, std::string
208 in STL mode.) Either or both cfile and str can be null.
210 This is a formatted print, and will insert
213 (For an unformatted stream, use the << operator.)
215 virtual void Print( FILE* cfile, int depth ) const = 0;
217 /** The world does not agree on whether white space should be kept or
218 not. In order to make everyone happy, these global, static functions
219 are provided to set whether or not TinyXml will condense all white space
220 into a single space or not. The default is to condense. Note changing this
221 value is not thread safe.
223 static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; }
225 /// Return the current white space setting.
226 static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace; }
228 /** Return the position, in the original source file, of this node or attribute.
229 The row and column are 1-based. (That is the first row and first column is
230 1,1). If the returns values are 0 or less, then the parser does not have
231 a row and column value.
233 Generally, the row and column value will be set when the TiXmlDocument::Load(),
234 TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set
235 when the DOM was created from operator>>.
237 The values reflect the initial load. Once the DOM is modified programmatically
238 (by adding or changing nodes and attributes) the new values will NOT update to
239 reflect changes in the document.
241 There is a minor performance cost to computing the row and column. Computation
242 can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value.
244 @sa TiXmlDocument::SetTabSize()
246 int Row() const { return location.row + 1; }
247 int Column() const { return location.col + 1; } ///< See Row()
249 void SetUserData( void* user ) { userData = user; } ///< Set a pointer to arbitrary user data.
250 void* GetUserData() { return userData; } ///< Get a pointer to arbitrary user data.
251 const void* GetUserData() const { return userData; } ///< Get a pointer to arbitrary user data.
253 // Table that returs, for a given lead byte, the total number of bytes
254 // in the UTF-8 sequence.
255 static const int utf8ByteTable[256];
257 virtual const char* Parse( const char* p,
258 TiXmlParsingData* data,
259 TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0;
261 /** Expands entities in a string. Note this should not contian the tag's '<', '>', etc,
262 or they will be transformed into entities!
264 static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out );
270 TIXML_ERROR_OPENING_FILE,
271 TIXML_ERROR_PARSING_ELEMENT,
272 TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
273 TIXML_ERROR_READING_ELEMENT_VALUE,
274 TIXML_ERROR_READING_ATTRIBUTES,
275 TIXML_ERROR_PARSING_EMPTY,
276 TIXML_ERROR_READING_END_TAG,
277 TIXML_ERROR_PARSING_UNKNOWN,
278 TIXML_ERROR_PARSING_COMMENT,
279 TIXML_ERROR_PARSING_DECLARATION,
280 TIXML_ERROR_DOCUMENT_EMPTY,
281 TIXML_ERROR_EMBEDDED_NULL,
282 TIXML_ERROR_PARSING_CDATA,
283 TIXML_ERROR_DOCUMENT_TOP_ONLY,
285 TIXML_ERROR_STRING_COUNT
290 static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding );
292 inline static bool IsWhiteSpace( char c )
294 return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' );
296 inline static bool IsWhiteSpace( int c )
299 return IsWhiteSpace( (char) c );
300 return false; // Again, only truly correct for English/Latin...but usually works.
304 static bool StreamWhiteSpace( std::istream * in, TIXML_STRING * tag );
305 static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag );
308 /* Reads an XML name into the string provided. Returns
309 a pointer just past the last character of the name,
310 or 0 if the function has an error.
312 static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding );
314 /* Reads text. Returns a pointer past the given end tag.
315 Wickedly complex options, but it keeps the (sensitive) code in one place.
317 static const char* ReadText( const char* in, // where to start
318 TIXML_STRING* text, // the string read
319 bool ignoreWhiteSpace, // whether to keep the white space
320 const char* endTag, // what ends this text
321 bool ignoreCase, // whether to ignore case in the end tag
322 TiXmlEncoding encoding ); // the current encoding
324 // If an entity has been found, transform it into a character.
325 static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding );
327 // Get a character, while interpreting entities.
328 // The length can be from 0 to 4 bytes.
329 inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding )
332 if ( encoding == TIXML_ENCODING_UTF8 )
334 *length = utf8ByteTable[ *((const unsigned char*)p) ];
335 assert( *length >= 0 && *length < 5 );
345 return GetEntity( p, _value, length, encoding );
351 //strncpy( _value, p, *length ); // lots of compilers don't like this function (unsafe),
352 // and the null terminator isn't needed
353 for( int i=0; p[i] && i<*length; ++i ) {
356 return p + (*length);
365 // Return true if the next characters in the stream are any of the endTag sequences.
366 // Ignore case only works for english, and should only be relied on when comparing
367 // to English words: StringEqual( p, "version", true ) is fine.
368 static bool StringEqual( const char* p,
371 TiXmlEncoding encoding );
373 static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
375 TiXmlCursor location;
377 /// Field containing a generic user pointer
380 // None of these methods are reliable for any language except English.
381 // Good for approximation, not great for accuracy.
382 static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding );
383 static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding );
384 inline static int ToLower( int v, TiXmlEncoding encoding )
386 if ( encoding == TIXML_ENCODING_UTF8 )
388 if ( v < 128 ) return tolower( v );
396 static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
399 TiXmlBase( const TiXmlBase& ); // not implemented.
400 void operator=( const TiXmlBase& base ); // not allowed.
405 unsigned int strLength;
411 MAX_ENTITY_LENGTH = 6
414 static Entity entity[ NUM_ENTITY ];
415 static bool condenseWhiteSpace;
419 /** The parent class for everything in the Document Object Model.
420 (Except for attributes).
421 Nodes have siblings, a parent, and children. A node can be
422 in a document, or stand on its own. The type of a TiXmlNode
423 can be queried, and it can be cast to its more defined type.
425 class cpPlugins_tinyxml_EXPORT TiXmlNode : public TiXmlBase
427 friend class TiXmlDocument;
428 friend class TiXmlElement;
433 /** An input stream operator, for every class. Tolerant of newlines and
434 formatting, but doesn't expect them.
436 friend std::istream& operator >> (std::istream& in, TiXmlNode& base);
438 /** An output stream operator, for every class. Note that this outputs
439 without any newlines or formatting, as opposed to Print(), which
440 includes tabs and new lines.
442 The operator<< and operator>> are not completely symmetric. Writing
443 a node to a stream is very well defined. You'll get a nice stream
444 of output, without any extra whitespace or newlines.
446 But reading is not as well defined. (As it always is.) If you create
447 a TiXmlElement (for example) and read that from an input stream,
448 the text needs to define an element or junk will result. This is
449 true of all input streams, but it's worth keeping in mind.
451 A TiXmlDocument will read nodes until it reads a root element, and
452 all the children of that root element.
454 friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base);
456 /// Appends the XML node or attribute to a std::string.
457 friend std::string& operator<< (std::string& out, const TiXmlNode& base );
461 /** The types of XML nodes supported by TinyXml. (All the
462 unsupported types are picked up by UNKNOWN.)
475 virtual ~TiXmlNode();
477 /** The meaning of 'value' changes for the specific type of
480 Document: filename of the xml file
481 Element: name of the element
482 Comment: the comment text
483 Unknown: the tag contents
484 Text: the text string
487 The subclasses will wrap this function.
489 const char *Value() const { return value.c_str (); }
492 /** Return Value() as a std::string. If you only use STL,
493 this is more efficient than calling Value().
494 Only available in STL mode.
496 const std::string& ValueStr() const { return value; }
499 const TIXML_STRING& ValueTStr() const { return value; }
501 /** Changes the value of the node. Defined as:
503 Document: filename of the xml file
504 Element: name of the element
505 Comment: the comment text
506 Unknown: the tag contents
507 Text: the text string
510 void SetValue(const char * _value) { value = _value;}
513 /// STL std::string form.
514 void SetValue( const std::string& _value ) { value = _value; }
517 /// Delete all the children of this node. Does not affect 'this'.
520 /// One step up the DOM.
521 TiXmlNode* Parent() { return parent; }
522 const TiXmlNode* Parent() const { return parent; }
524 const TiXmlNode* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children.
525 TiXmlNode* FirstChild() { return firstChild; }
526 const TiXmlNode* FirstChild( const char * value ) const; ///< The first child of this node with the matching 'value'. Will be null if none found.
527 /// The first child of this node with the matching 'value'. Will be null if none found.
528 TiXmlNode* FirstChild( const char * _value ) {
529 // Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe)
530 // call the method, cast the return back to non-const.
531 return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value ));
533 const TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children.
534 TiXmlNode* LastChild() { return lastChild; }
536 const TiXmlNode* LastChild( const char * value ) const; /// The last child of this node matching 'value'. Will be null if there are no children.
537 TiXmlNode* LastChild( const char * _value ) {
538 return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value ));
542 const TiXmlNode* FirstChild( const std::string& _value ) const { return FirstChild (_value.c_str ()); } ///< STL std::string form.
543 TiXmlNode* FirstChild( const std::string& _value ) { return FirstChild (_value.c_str ()); } ///< STL std::string form.
544 const TiXmlNode* LastChild( const std::string& _value ) const { return LastChild (_value.c_str ()); } ///< STL std::string form.
545 TiXmlNode* LastChild( const std::string& _value ) { return LastChild (_value.c_str ()); } ///< STL std::string form.
548 /** An alternate way to walk the children of a node.
549 One way to iterate over nodes is:
551 for( child = parent->FirstChild(); child; child = child->NextSibling() )
554 IterateChildren does the same thing with the syntax:
557 while( child = parent->IterateChildren( child ) )
560 IterateChildren takes the previous child as input and finds
561 the next one. If the previous child is null, it returns the
562 first. IterateChildren will return null when done.
564 const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const;
565 TiXmlNode* IterateChildren( const TiXmlNode* previous ) {
566 return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) );
569 /// This flavor of IterateChildren searches for children with a particular 'value'
570 const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const;
571 TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) {
572 return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) );
576 const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form.
577 TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form.
580 /** Add a new node related to this. Adds a child past the LastChild.
581 Returns a pointer to the new object or NULL if an error occured.
583 TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
586 /** Add a new node related to this. Adds a child past the LastChild.
588 NOTE: the node to be added is passed by pointer, and will be
589 henceforth owned (and deleted) by tinyXml. This method is efficient
590 and avoids an extra copy, but should be used with care as it
591 uses a different memory model than the other insert functions.
595 TiXmlNode* LinkEndChild( TiXmlNode* addThis );
597 /** Add a new node related to this. Adds a child before the specified child.
598 Returns a pointer to the new object or NULL if an error occured.
600 TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
602 /** Add a new node related to this. Adds a child after the specified child.
603 Returns a pointer to the new object or NULL if an error occured.
605 TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis );
607 /** Replace a child of this node.
608 Returns a pointer to the new object or NULL if an error occured.
610 TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
612 /// Delete a child of this node.
613 bool RemoveChild( TiXmlNode* removeThis );
615 /// Navigate to a sibling node.
616 const TiXmlNode* PreviousSibling() const { return prev; }
617 TiXmlNode* PreviousSibling() { return prev; }
619 /// Navigate to a sibling node.
620 const TiXmlNode* PreviousSibling( const char * ) const;
621 TiXmlNode* PreviousSibling( const char *_prev ) {
622 return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) );
626 const TiXmlNode* PreviousSibling( const std::string& _value ) const { return PreviousSibling (_value.c_str ()); } ///< STL std::string form.
627 TiXmlNode* PreviousSibling( const std::string& _value ) { return PreviousSibling (_value.c_str ()); } ///< STL std::string form.
628 const TiXmlNode* NextSibling( const std::string& _value) const { return NextSibling (_value.c_str ()); } ///< STL std::string form.
629 TiXmlNode* NextSibling( const std::string& _value) { return NextSibling (_value.c_str ()); } ///< STL std::string form.
632 /// Navigate to a sibling node.
633 const TiXmlNode* NextSibling() const { return next; }
634 TiXmlNode* NextSibling() { return next; }
636 /// Navigate to a sibling node with the given 'value'.
637 const TiXmlNode* NextSibling( const char * ) const;
638 TiXmlNode* NextSibling( const char* _next ) {
639 return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) );
642 /** Convenience function to get through elements.
643 Calls NextSibling and ToElement. Will skip all non-Element
644 nodes. Returns 0 if there is not another element.
646 const TiXmlElement* NextSiblingElement() const;
647 TiXmlElement* NextSiblingElement() {
648 return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() );
651 /** Convenience function to get through elements.
652 Calls NextSibling and ToElement. Will skip all non-Element
653 nodes. Returns 0 if there is not another element.
655 const TiXmlElement* NextSiblingElement( const char * ) const;
656 TiXmlElement* NextSiblingElement( const char *_next ) {
657 return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) );
661 const TiXmlElement* NextSiblingElement( const std::string& _value) const { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form.
662 TiXmlElement* NextSiblingElement( const std::string& _value) { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form.
665 /// Convenience function to get through elements.
666 const TiXmlElement* FirstChildElement() const;
667 TiXmlElement* FirstChildElement() {
668 return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() );
671 /// Convenience function to get through elements.
672 const TiXmlElement* FirstChildElement( const char * _value ) const;
673 TiXmlElement* FirstChildElement( const char * _value ) {
674 return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) );
678 const TiXmlElement* FirstChildElement( const std::string& _value ) const { return FirstChildElement (_value.c_str ()); } ///< STL std::string form.
679 TiXmlElement* FirstChildElement( const std::string& _value ) { return FirstChildElement (_value.c_str ()); } ///< STL std::string form.
682 /** Query the type (as an enumerated value, above) of this node.
683 The possible types are: DOCUMENT, ELEMENT, COMMENT,
684 UNKNOWN, TEXT, and DECLARATION.
686 int Type() const { return type; }
688 /** Return a pointer to the Document this node lives in.
689 Returns null if not in a document.
691 const TiXmlDocument* GetDocument() const;
692 TiXmlDocument* GetDocument() {
693 return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() );
696 /// Returns true if this node has no children.
697 bool NoChildren() const { return !firstChild; }
699 virtual const TiXmlDocument* ToDocument() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
700 virtual const TiXmlElement* ToElement() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
701 virtual const TiXmlComment* ToComment() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
702 virtual const TiXmlUnknown* ToUnknown() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
703 virtual const TiXmlText* ToText() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
704 virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
706 virtual TiXmlDocument* ToDocument() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
707 virtual TiXmlElement* ToElement() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
708 virtual TiXmlComment* ToComment() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
709 virtual TiXmlUnknown* ToUnknown() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
710 virtual TiXmlText* ToText() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
711 virtual TiXmlDeclaration* ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
713 /** Create an exact duplicate of this node and return it. The memory must be deleted
716 virtual TiXmlNode* Clone() const = 0;
718 /** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the
719 XML tree will be conditionally visited and the host will be called back
720 via the TiXmlVisitor interface.
722 This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse
723 the XML for the callbacks, so the performance of TinyXML is unchanged by using this
724 interface versus any other.)
726 The interface has been based on ideas from:
728 - http://www.saxproject.org/
729 - http://c2.com/cgi/wiki?HierarchicalVisitorPattern
731 Which are both good references for "visiting".
733 An example of using Accept():
735 TiXmlPrinter printer;
736 tinyxmlDoc.Accept( &printer );
737 const char* xmlcstr = printer.CStr();
740 virtual bool Accept( TiXmlVisitor* visitor ) const = 0;
743 TiXmlNode( NodeType _type );
745 // Copy to the allocated object. Shared functionality between Clone, Copy constructor,
746 // and the assignment operator.
747 void CopyTo( TiXmlNode* target ) const;
750 // The real work of the input operator.
751 virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0;
754 // Figure out what is at *p, and parse it. Returns null if it is not an xml node.
755 TiXmlNode* Identify( const char* start, TiXmlEncoding encoding );
760 TiXmlNode* firstChild;
761 TiXmlNode* lastChild;
769 TiXmlNode( const TiXmlNode& ); // not implemented.
770 void operator=( const TiXmlNode& base ); // not allowed.
774 /** An attribute is a name-value pair. Elements have an arbitrary
775 number of attributes, each with a unique name.
777 @note The attributes are not TiXmlNodes, since they are not
778 part of the tinyXML document object model. There are other
779 suggested ways to look at this problem.
781 class cpPlugins_tinyxml_EXPORT TiXmlAttribute : public TiXmlBase
783 friend class TiXmlAttributeSet;
786 /// Construct an empty attribute.
787 TiXmlAttribute() : TiXmlBase()
794 /// std::string constructor.
795 TiXmlAttribute( const std::string& _name, const std::string& _value )
804 /// Construct an attribute with a name and value.
805 TiXmlAttribute( const char * _name, const char * _value )
813 const char* Name() const { return name.c_str(); } ///< Return the name of this attribute.
814 const char* Value() const { return value.c_str(); } ///< Return the value of this attribute.
816 const std::string& ValueStr() const { return value; } ///< Return the value of this attribute.
818 int IntValue() const; ///< Return the value of this attribute, converted to an integer.
819 double DoubleValue() const; ///< Return the value of this attribute, converted to a double.
821 // Get the tinyxml string representation
822 const TIXML_STRING& NameTStr() const { return name; }
824 /** QueryIntValue examines the value string. It is an alternative to the
825 IntValue() method with richer error checking.
826 If the value is an integer, it is stored in 'value' and
827 the call returns TIXML_SUCCESS. If it is not
828 an integer, it returns TIXML_WRONG_TYPE.
830 A specialized but useful call. Note that for success it returns 0,
831 which is the opposite of almost all other TinyXml calls.
833 int QueryIntValue( int* _value ) const;
834 /// QueryDoubleValue examines the value string. See QueryIntValue().
835 int QueryDoubleValue( double* _value ) const;
837 void SetName( const char* _name ) { name = _name; } ///< Set the name of this attribute.
838 void SetValue( const char* _value ) { value = _value; } ///< Set the value.
840 void SetIntValue( int _value ); ///< Set the value from an integer.
841 void SetDoubleValue( double _value ); ///< Set the value from a double.
844 /// STL std::string form.
845 void SetName( const std::string& _name ) { name = _name; }
846 /// STL std::string form.
847 void SetValue( const std::string& _value ) { value = _value; }
850 /// Get the next sibling attribute in the DOM. Returns null at end.
851 const TiXmlAttribute* Next() const;
852 TiXmlAttribute* Next() {
853 return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() );
856 /// Get the previous sibling attribute in the DOM. Returns null at beginning.
857 const TiXmlAttribute* Previous() const;
858 TiXmlAttribute* Previous() {
859 return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() );
862 bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
863 bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; }
864 bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; }
866 /* Attribute parsing starts: first letter of the name
867 returns: the next char after the value end quote
869 virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
871 // Prints this Attribute to a FILE stream.
872 virtual void Print( FILE* cfile, int depth ) const {
873 Print( cfile, depth, 0 );
875 void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
878 // Set the document pointer so the attribute can report errors.
879 void SetDocument( TiXmlDocument* doc ) { document = doc; }
882 TiXmlAttribute( const TiXmlAttribute& ); // not implemented.
883 void operator=( const TiXmlAttribute& base ); // not allowed.
885 TiXmlDocument* document; // A pointer back to a document, for error reporting.
888 TiXmlAttribute* prev;
889 TiXmlAttribute* next;
893 /* A class used to manage a group of attributes.
894 It is only used internally, both by the ELEMENT and the DECLARATION.
896 The set can be changed transparent to the Element and Declaration
897 classes that use it, but NOT transparent to the Attribute
898 which has to implement a next() and previous() method. Which makes
899 it a bit problematic and prevents the use of STL.
901 This version is implemented with circular lists because:
902 - I like circular lists
903 - it demonstrates some independence from the (typical) doubly linked list.
905 class cpPlugins_tinyxml_EXPORT TiXmlAttributeSet
909 ~TiXmlAttributeSet();
911 void Add( TiXmlAttribute* attribute );
912 void Remove( TiXmlAttribute* attribute );
914 const TiXmlAttribute* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
915 TiXmlAttribute* First() { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
916 const TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
917 TiXmlAttribute* Last() { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
919 TiXmlAttribute* Find( const char* _name ) const;
920 TiXmlAttribute* FindOrCreate( const char* _name );
922 # ifdef TIXML_USE_STL
923 TiXmlAttribute* Find( const std::string& _name ) const;
924 TiXmlAttribute* FindOrCreate( const std::string& _name );
929 //*ME: Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element),
930 //*ME: this class must be also use a hidden/disabled copy-constructor !!!
931 TiXmlAttributeSet( const TiXmlAttributeSet& ); // not allowed
932 void operator=( const TiXmlAttributeSet& ); // not allowed (as TiXmlAttribute)
934 TiXmlAttribute sentinel;
938 /** The element is a container class. It has a value, the element name,
939 and can contain other elements, text, comments, and unknowns.
940 Elements also contain an arbitrary number of attributes.
942 class cpPlugins_tinyxml_EXPORT TiXmlElement : public TiXmlNode
945 /// Construct an element.
946 TiXmlElement (const char * in_value);
949 /// std::string constructor.
950 TiXmlElement( const std::string& _value );
953 TiXmlElement( const TiXmlElement& );
955 void operator=( const TiXmlElement& base );
957 virtual ~TiXmlElement();
959 /** Given an attribute name, Attribute() returns the value
960 for the attribute of that name, or null if none exists.
962 const char* Attribute( const char* name ) const;
964 /** Given an attribute name, Attribute() returns the value
965 for the attribute of that name, or null if none exists.
966 If the attribute exists and can be converted to an integer,
967 the integer value will be put in the return 'i', if 'i'
970 const char* Attribute( const char* name, int* i ) const;
972 /** Given an attribute name, Attribute() returns the value
973 for the attribute of that name, or null if none exists.
974 If the attribute exists and can be converted to an double,
975 the double value will be put in the return 'd', if 'd'
978 const char* Attribute( const char* name, double* d ) const;
980 /** QueryIntAttribute examines the attribute - it is an alternative to the
981 Attribute() method with richer error checking.
982 If the attribute is an integer, it is stored in 'value' and
983 the call returns TIXML_SUCCESS. If it is not
984 an integer, it returns TIXML_WRONG_TYPE. If the attribute
985 does not exist, then TIXML_NO_ATTRIBUTE is returned.
987 int QueryIntAttribute( const char* name, int* _value ) const;
988 /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute().
989 int QueryDoubleAttribute( const char* name, double* _value ) const;
990 /// QueryFloatAttribute examines the attribute - see QueryIntAttribute().
991 int QueryFloatAttribute( const char* name, float* _value ) const {
993 int result = QueryDoubleAttribute( name, &d );
994 if ( result == TIXML_SUCCESS ) {
1000 #ifdef TIXML_USE_STL
1001 /// QueryStringAttribute examines the attribute - see QueryIntAttribute().
1002 int QueryStringAttribute( const char* name, std::string* _value ) const {
1003 const char* cstr = Attribute( name );
1005 *_value = std::string( cstr );
1006 return TIXML_SUCCESS;
1008 return TIXML_NO_ATTRIBUTE;
1011 /** Template form of the attribute query which will try to read the
1012 attribute into the specified type. Very easy, very powerful, but
1013 be careful to make sure to call this with the correct type.
1015 NOTE: This method doesn't work correctly for 'string' types that contain spaces.
1017 @return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE
1019 template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const
1021 const TiXmlAttribute* node = attributeSet.Find( name );
1023 return TIXML_NO_ATTRIBUTE;
1025 std::stringstream sstream( node->ValueStr() );
1026 sstream >> *outValue;
1027 if ( !sstream.fail() )
1028 return TIXML_SUCCESS;
1029 return TIXML_WRONG_TYPE;
1032 int QueryValueAttribute( const std::string& name, std::string* outValue ) const
1034 const TiXmlAttribute* node = attributeSet.Find( name );
1036 return TIXML_NO_ATTRIBUTE;
1037 *outValue = node->ValueStr();
1038 return TIXML_SUCCESS;
1042 /** Sets an attribute of name to a given value. The attribute
1043 will be created if it does not exist, or changed if it does.
1045 void SetAttribute( const char* name, const char * _value );
1047 #ifdef TIXML_USE_STL
1048 const std::string* Attribute( const std::string& name ) const;
1049 const std::string* Attribute( const std::string& name, int* i ) const;
1050 const std::string* Attribute( const std::string& name, double* d ) const;
1051 int QueryIntAttribute( const std::string& name, int* _value ) const;
1052 int QueryDoubleAttribute( const std::string& name, double* _value ) const;
1054 /// STL std::string form.
1055 void SetAttribute( const std::string& name, const std::string& _value );
1056 ///< STL std::string form.
1057 void SetAttribute( const std::string& name, int _value );
1058 ///< STL std::string form.
1059 void SetDoubleAttribute( const std::string& name, double value );
1062 /** Sets an attribute of name to a given value. The attribute
1063 will be created if it does not exist, or changed if it does.
1065 void SetAttribute( const char * name, int value );
1067 /** Sets an attribute of name to a given value. The attribute
1068 will be created if it does not exist, or changed if it does.
1070 void SetDoubleAttribute( const char * name, double value );
1072 /** Deletes an attribute with the given name.
1074 void RemoveAttribute( const char * name );
1075 #ifdef TIXML_USE_STL
1076 void RemoveAttribute( const std::string& name ) { RemoveAttribute (name.c_str ()); } ///< STL std::string form.
1079 const TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); } ///< Access the first attribute in this element.
1080 TiXmlAttribute* FirstAttribute() { return attributeSet.First(); }
1081 const TiXmlAttribute* LastAttribute() const { return attributeSet.Last(); } ///< Access the last attribute in this element.
1082 TiXmlAttribute* LastAttribute() { return attributeSet.Last(); }
1084 /** Convenience function for easy access to the text inside an element. Although easy
1085 and concise, GetText() is limited compared to getting the TiXmlText child
1086 and accessing it directly.
1088 If the first child of 'this' is a TiXmlText, the GetText()
1089 returns the character string of the Text node, else null is returned.
1091 This is a convenient method for getting the text of simple contained text:
1093 <foo>This is text</foo>
1094 const char* str = fooElement->GetText();
1097 'str' will be a pointer to "This is text".
1099 Note that this function can be misleading. If the element foo was created from
1102 <foo><b>This is text</b></foo>
1105 then the value of str would be null. The first child node isn't a text node, it is
1106 another element. From this XML:
1108 <foo>This is <b>text</b></foo>
1110 GetText() will return "This is ".
1112 WARNING: GetText() accesses a child node - don't become confused with the
1113 similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are
1114 safe type casts on the referenced node.
1116 const char* GetText() const;
1118 /// Creates a new Element and returns it - the returned element is a copy.
1119 virtual TiXmlNode* Clone() const;
1120 // Print the Element to a FILE stream.
1121 virtual void Print( FILE* cfile, int depth ) const;
1123 /* Attribtue parsing starts: next char past '<'
1124 returns: next char past '>'
1126 virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
1128 virtual const TiXmlElement* ToElement() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1129 virtual TiXmlElement* ToElement() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1131 /** Walk the XML tree visiting this node and all of its children.
1133 virtual bool Accept( TiXmlVisitor* visitor ) const;
1137 void CopyTo( TiXmlElement* target ) const;
1138 void ClearThis(); // like clear, but initializes 'this' object as well
1140 // Used to be public [internal use]
1141 #ifdef TIXML_USE_STL
1142 virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
1145 Reads the "value" of the element -- another element, or text.
1146 This should terminate with the current end tag.
1148 const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding );
1151 TiXmlAttributeSet attributeSet;
1157 class TiXmlComment : public TiXmlNode
1160 /// Constructs an empty comment.
1161 TiXmlComment() : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {}
1162 /// Construct a comment from text.
1163 TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {
1166 TiXmlComment( const TiXmlComment& );
1167 void operator=( const TiXmlComment& base );
1169 virtual ~TiXmlComment() {}
1171 /// Returns a copy of this Comment.
1172 virtual TiXmlNode* Clone() const;
1173 // Write this Comment to a FILE stream.
1174 virtual void Print( FILE* cfile, int depth ) const;
1176 /* Attribtue parsing starts: at the ! of the !--
1177 returns: next char past '>'
1179 virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
1181 virtual const TiXmlComment* ToComment() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1182 virtual TiXmlComment* ToComment() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1184 /** Walk the XML tree visiting this node and all of its children.
1186 virtual bool Accept( TiXmlVisitor* visitor ) const;
1189 void CopyTo( TiXmlComment* target ) const;
1191 // used to be public
1192 #ifdef TIXML_USE_STL
1193 virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
1195 // virtual void StreamOut( TIXML_OSTREAM * out ) const;
1202 /** XML text. A text node can have 2 ways to output the next. "normal" output
1203 and CDATA. It will default to the mode it was parsed from the XML file and
1204 you generally want to leave it alone, but you can change the output mode with
1205 SetCDATA() and query it with CDATA().
1207 class TiXmlText : public TiXmlNode
1209 friend class TiXmlElement;
1211 /** Constructor for text element. By default, it is treated as
1212 normal, encoded text. If you want it be output as a CDATA text
1213 element, set the parameter _cdata to 'true'
1215 TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT)
1217 SetValue( initValue );
1220 virtual ~TiXmlText() {}
1222 #ifdef TIXML_USE_STL
1224 TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT)
1226 SetValue( initValue );
1231 TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TINYXML_TEXT ) { copy.CopyTo( this ); }
1232 void operator=( const TiXmlText& base ) { base.CopyTo( this ); }
1234 // Write this text object to a FILE stream.
1235 virtual void Print( FILE* cfile, int depth ) const;
1237 /// Queries whether this represents text using a CDATA section.
1238 bool CDATA() const { return cdata; }
1239 /// Turns on or off a CDATA representation of text.
1240 void SetCDATA( bool _cdata ) { cdata = _cdata; }
1242 virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
1244 virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1245 virtual TiXmlText* ToText() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1247 /** Walk the XML tree visiting this node and all of its children.
1249 virtual bool Accept( TiXmlVisitor* content ) const;
1252 /// [internal use] Creates a new Element and returns it.
1253 virtual TiXmlNode* Clone() const;
1254 void CopyTo( TiXmlText* target ) const;
1256 bool Blank() const; // returns true if all white space and new lines
1258 #ifdef TIXML_USE_STL
1259 virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
1263 bool cdata; // true if this should be input and output as a CDATA style text element
1267 /** In correct XML the declaration is the first entry in the file.
1269 <?xml version="1.0" standalone="yes"?>
1272 TinyXml will happily read or write files without a declaration,
1273 however. There are 3 possible attributes to the declaration:
1274 version, encoding, and standalone.
1276 Note: In this version of the code, the attributes are
1277 handled as special cases, not generic attributes, simply
1278 because there can only be at most 3 and they are always the same.
1280 class cpPlugins_tinyxml_EXPORT TiXmlDeclaration : public TiXmlNode
1283 /// Construct an empty declaration.
1284 TiXmlDeclaration() : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) {}
1286 #ifdef TIXML_USE_STL
1288 TiXmlDeclaration( const std::string& _version,
1289 const std::string& _encoding,
1290 const std::string& _standalone );
1294 TiXmlDeclaration( const char* _version,
1295 const char* _encoding,
1296 const char* _standalone );
1298 TiXmlDeclaration( const TiXmlDeclaration& copy );
1299 void operator=( const TiXmlDeclaration& copy );
1301 virtual ~TiXmlDeclaration() {}
1303 /// Version. Will return an empty string if none was found.
1304 const char *Version() const { return version.c_str (); }
1305 /// Encoding. Will return an empty string if none was found.
1306 const char *Encoding() const { return encoding.c_str (); }
1307 /// Is this a standalone document?
1308 const char *Standalone() const { return standalone.c_str (); }
1310 /// Creates a copy of this Declaration and returns it.
1311 virtual TiXmlNode* Clone() const;
1312 // Print this declaration to a FILE stream.
1313 virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
1314 virtual void Print( FILE* cfile, int depth ) const {
1315 Print( cfile, depth, 0 );
1318 virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
1320 virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1321 virtual TiXmlDeclaration* ToDeclaration() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1323 /** Walk the XML tree visiting this node and all of its children.
1325 virtual bool Accept( TiXmlVisitor* visitor ) const;
1328 void CopyTo( TiXmlDeclaration* target ) const;
1329 // used to be public
1330 #ifdef TIXML_USE_STL
1331 virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
1336 TIXML_STRING version;
1337 TIXML_STRING encoding;
1338 TIXML_STRING standalone;
1342 /** Any tag that tinyXml doesn't recognize is saved as an
1343 unknown. It is a tag of text, but should not be modified.
1344 It will be written back to the XML, unchanged, when the file
1347 DTD tags get thrown into TiXmlUnknowns.
1349 class TiXmlUnknown : public TiXmlNode
1352 TiXmlUnknown() : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN ) {}
1353 virtual ~TiXmlUnknown() {}
1355 TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN ) { copy.CopyTo( this ); }
1356 void operator=( const TiXmlUnknown& copy ) { copy.CopyTo( this ); }
1358 /// Creates a copy of this Unknown and returns it.
1359 virtual TiXmlNode* Clone() const;
1360 // Print this Unknown to a FILE stream.
1361 virtual void Print( FILE* cfile, int depth ) const;
1363 virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
1365 virtual const TiXmlUnknown* ToUnknown() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1366 virtual TiXmlUnknown* ToUnknown() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1368 /** Walk the XML tree visiting this node and all of its children.
1370 virtual bool Accept( TiXmlVisitor* content ) const;
1373 void CopyTo( TiXmlUnknown* target ) const;
1375 #ifdef TIXML_USE_STL
1376 virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
1384 /** Always the top level node. A document binds together all the
1385 XML pieces. It can be saved, loaded, and printed to the screen.
1386 The 'value' of a document node is the xml file name.
1388 class cpPlugins_tinyxml_EXPORT TiXmlDocument : public TiXmlNode
1391 /// Create an empty document, that has no name.
1393 /// Create a document with a name. The name of the document is also the filename of the xml.
1394 TiXmlDocument( const char * documentName );
1396 #ifdef TIXML_USE_STL
1398 TiXmlDocument( const std::string& documentName );
1401 TiXmlDocument( const TiXmlDocument& copy );
1402 void operator=( const TiXmlDocument& copy );
1404 virtual ~TiXmlDocument() {}
1406 /** Load a file using the current document value.
1407 Returns true if successful. Will delete any existing
1408 document data before loading.
1410 bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1411 /// Save a file using the current document value. Returns true if successful.
1412 bool SaveFile() const;
1413 /// Load a file using the given filename. Returns true if successful.
1414 bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1415 /// Save a file using the given filename. Returns true if successful.
1416 bool SaveFile( const char * filename ) const;
1417 /** Load a file using the given FILE*. Returns true if successful. Note that this method
1418 doesn't stream - the entire object pointed at by the FILE*
1419 will be interpreted as an XML file. TinyXML doesn't stream in XML from the current
1420 file location. Streaming may be added in the future.
1422 bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1423 /// Save a file using the given FILE*. Returns true if successful.
1424 bool SaveFile( FILE* ) const;
1426 #ifdef TIXML_USE_STL
1427 bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ) ///< STL std::string version.
1429 return LoadFile( filename.c_str(), encoding );
1431 bool SaveFile( const std::string& filename ) const ///< STL std::string version.
1433 return SaveFile( filename.c_str() );
1437 /** Parse the given null terminated block of xml data. Passing in an encoding to this
1438 method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml
1439 to use that encoding, regardless of what TinyXml might otherwise try to detect.
1441 virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1443 /** Get the root element -- the only top level element -- of the document.
1444 In well formed XML, there should only be one. TinyXml is tolerant of
1445 multiple elements at the document level.
1447 const TiXmlElement* RootElement() const { return FirstChildElement(); }
1448 TiXmlElement* RootElement() { return FirstChildElement(); }
1450 /** If an error occurs, Error will be set to true. Also,
1451 - The ErrorId() will contain the integer identifier of the error (not generally useful)
1452 - The ErrorDesc() method will return the name of the error. (very useful)
1453 - The ErrorRow() and ErrorCol() will return the location of the error (if known)
1455 bool Error() const { return error; }
1457 /// Contains a textual (english) description of the error if one occurs.
1458 const char * ErrorDesc() const { return errorDesc.c_str (); }
1460 /** Generally, you probably want the error string ( ErrorDesc() ). But if you
1461 prefer the ErrorId, this function will fetch it.
1463 int ErrorId() const { return errorId; }
1465 /** Returns the location (if known) of the error. The first column is column 1,
1466 and the first row is row 1. A value of 0 means the row and column wasn't applicable
1467 (memory errors, for example, have no row/column) or the parser lost the error. (An
1468 error in the error reporting, in that case.)
1470 @sa SetTabSize, Row, Column
1472 int ErrorRow() const { return errorLocation.row+1; }
1473 int ErrorCol() const { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow()
1475 /** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol())
1476 to report the correct values for row and column. It does not change the output
1477 or input in any way.
1479 By calling this method, with a tab size
1480 greater than 0, the row and column of each node and attribute is stored
1481 when the file is loaded. Very useful for tracking the DOM back in to
1484 The tab size is required for calculating the location of nodes. If not
1485 set, the default of 4 is used. The tabsize is set per document. Setting
1486 the tabsize to 0 disables row/column tracking.
1488 Note that row and column tracking is not supported when using operator>>.
1490 The tab size needs to be enabled before the parse or load. Correct usage:
1493 doc.SetTabSize( 8 );
1494 doc.Load( "myfile.xml" );
1499 void SetTabSize( int _tabsize ) { tabsize = _tabsize; }
1501 int TabSize() const { return tabsize; }
1503 /** If you have handled the error, it can be reset with this call. The error
1504 state is automatically cleared if you Parse a new XML block.
1506 void ClearError() { error = false;
1509 errorLocation.row = errorLocation.col = 0;
1510 //errorLocation.last = 0;
1513 /** Write the document to standard out using formatted printing ("pretty print"). */
1514 void Print() const { Print( stdout, 0 ); }
1516 /* Write the document to a string using formatted printing ("pretty print"). This
1517 will allocate a character array (new char[]) and return it as a pointer. The
1518 calling code pust call delete[] on the return char* to avoid a memory leak.
1520 //char* PrintToMemory() const;
1522 /// Print this Document to a FILE stream.
1523 virtual void Print( FILE* cfile, int depth = 0 ) const;
1525 void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding );
1527 virtual const TiXmlDocument* ToDocument() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1528 virtual TiXmlDocument* ToDocument() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1530 /** Walk the XML tree visiting this node and all of its children.
1532 virtual bool Accept( TiXmlVisitor* content ) const;
1536 virtual TiXmlNode* Clone() const;
1537 #ifdef TIXML_USE_STL
1538 virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
1542 void CopyTo( TiXmlDocument* target ) const;
1546 TIXML_STRING errorDesc;
1548 TiXmlCursor errorLocation;
1549 bool useMicrosoftBOM; // the UTF-8 BOM were found when read. Note this, and try to write.
1554 A TiXmlHandle is a class that wraps a node pointer with null checks; this is
1555 an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml
1556 DOM structure. It is a separate utility class.
1561 <Element attributeA = "valueA">
1562 <Child attributeB = "value1" />
1563 <Child attributeB = "value2" />
1568 Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very
1569 easy to write a *lot* of code that looks like:
1572 TiXmlElement* root = document.FirstChildElement( "Document" );
1575 TiXmlElement* element = root->FirstChildElement( "Element" );
1578 TiXmlElement* child = element->FirstChildElement( "Child" );
1581 TiXmlElement* child2 = child->NextSiblingElement( "Child" );
1584 // Finally do something useful.
1587 And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity
1588 of such code. A TiXmlHandle checks for null pointers so it is perfectly safe
1592 TiXmlHandle docHandle( &document );
1593 TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement();
1596 // do something useful
1599 Which is MUCH more concise and useful.
1601 It is also safe to copy handles - internally they are nothing more than node pointers.
1603 TiXmlHandle handleCopy = handle;
1606 What they should not be used for is iteration:
1612 TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement();
1620 It seems reasonable, but it is in fact two embedded while loops. The Child method is
1621 a linear walk to find the element, so this code would iterate much more than it needs
1622 to. Instead, prefer:
1625 TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement();
1627 for( child; child; child=child->NextSiblingElement() )
1636 /// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
1637 TiXmlHandle( TiXmlNode* _node ) { this->node = _node; }
1638 /// Copy constructor
1639 TiXmlHandle( const TiXmlHandle& ref ) { this->node = ref.node; }
1640 TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; }
1642 /// Return a handle to the first child node.
1643 TiXmlHandle FirstChild() const;
1644 /// Return a handle to the first child node with the given name.
1645 TiXmlHandle FirstChild( const char * value ) const;
1646 /// Return a handle to the first child element.
1647 TiXmlHandle FirstChildElement() const;
1648 /// Return a handle to the first child element with the given name.
1649 TiXmlHandle FirstChildElement( const char * value ) const;
1651 /** Return a handle to the "index" child with the given name.
1652 The first child is 0, the second 1, etc.
1654 TiXmlHandle Child( const char* value, int index ) const;
1655 /** Return a handle to the "index" child.
1656 The first child is 0, the second 1, etc.
1658 TiXmlHandle Child( int index ) const;
1659 /** Return a handle to the "index" child element with the given name.
1660 The first child element is 0, the second 1, etc. Note that only TiXmlElements
1661 are indexed: other types are not counted.
1663 TiXmlHandle ChildElement( const char* value, int index ) const;
1664 /** Return a handle to the "index" child element.
1665 The first child element is 0, the second 1, etc. Note that only TiXmlElements
1666 are indexed: other types are not counted.
1668 TiXmlHandle ChildElement( int index ) const;
1670 #ifdef TIXML_USE_STL
1671 TiXmlHandle FirstChild( const std::string& _value ) const { return FirstChild( _value.c_str() ); }
1672 TiXmlHandle FirstChildElement( const std::string& _value ) const { return FirstChildElement( _value.c_str() ); }
1674 TiXmlHandle Child( const std::string& _value, int index ) const { return Child( _value.c_str(), index ); }
1675 TiXmlHandle ChildElement( const std::string& _value, int index ) const { return ChildElement( _value.c_str(), index ); }
1678 /** Return the handle as a TiXmlNode. This may return null.
1680 TiXmlNode* ToNode() const { return node; }
1681 /** Return the handle as a TiXmlElement. This may return null.
1683 TiXmlElement* ToElement() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
1684 /** Return the handle as a TiXmlText. This may return null.
1686 TiXmlText* ToText() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
1687 /** Return the handle as a TiXmlUnknown. This may return null.
1689 TiXmlUnknown* ToUnknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
1691 /** @deprecated use ToNode.
1692 Return the handle as a TiXmlNode. This may return null.
1694 TiXmlNode* Node() const { return ToNode(); }
1695 /** @deprecated use ToElement.
1696 Return the handle as a TiXmlElement. This may return null.
1698 TiXmlElement* Element() const { return ToElement(); }
1699 /** @deprecated use ToText()
1700 Return the handle as a TiXmlText. This may return null.
1702 TiXmlText* Text() const { return ToText(); }
1703 /** @deprecated use ToUnknown()
1704 Return the handle as a TiXmlUnknown. This may return null.
1706 TiXmlUnknown* Unknown() const { return ToUnknown(); }
1713 /** Print to memory functionality. The TiXmlPrinter is useful when you need to:
1715 -# Print to memory (especially in non-STL mode)
1716 -# Control formatting (line endings, etc.)
1718 When constructed, the TiXmlPrinter is in its default "pretty printing" mode.
1719 Before calling Accept() you can call methods to control the printing
1720 of the XML document. After TiXmlNode::Accept() is called, the printed document can
1721 be accessed via the CStr(), Str(), and Size() methods.
1723 TiXmlPrinter uses the Visitor API.
1725 TiXmlPrinter printer;
1726 printer.SetIndent( "\t" );
1728 doc.Accept( &printer );
1729 fprintf( stdout, "%s", printer.CStr() );
1732 class TiXmlPrinter : public TiXmlVisitor
1735 TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ),
1736 buffer(), indent( " " ), lineBreak( "\n" ) {}
1738 virtual bool VisitEnter( const TiXmlDocument& doc );
1739 virtual bool VisitExit( const TiXmlDocument& doc );
1741 virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute );
1742 virtual bool VisitExit( const TiXmlElement& element );
1744 virtual bool Visit( const TiXmlDeclaration& declaration );
1745 virtual bool Visit( const TiXmlText& text );
1746 virtual bool Visit( const TiXmlComment& comment );
1747 virtual bool Visit( const TiXmlUnknown& unknown );
1749 /** Set the indent characters for printing. By default 4 spaces
1750 but tab (\t) is also useful, or null/empty string for no indentation.
1752 void SetIndent( const char* _indent ) { indent = _indent ? _indent : "" ; }
1753 /// Query the indention string.
1754 const char* Indent() { return indent.c_str(); }
1755 /** Set the line breaking string. By default set to newline (\n).
1756 Some operating systems prefer other characters, or can be
1757 set to the null/empty string for no indenation.
1759 void SetLineBreak( const char* _lineBreak ) { lineBreak = _lineBreak ? _lineBreak : ""; }
1760 /// Query the current line breaking string.
1761 const char* LineBreak() { return lineBreak.c_str(); }
1763 /** Switch over to "stream printing" which is the most dense formatting without
1764 linebreaks. Common when the XML is needed for network transmission.
1766 void SetStreamPrinting() { indent = "";
1769 /// Return the result.
1770 const char* CStr() { return buffer.c_str(); }
1771 /// Return the length of the result string.
1772 size_t Size() { return buffer.size(); }
1774 #ifdef TIXML_USE_STL
1775 /// Return the result.
1776 const std::string& Str() { return buffer; }
1781 for( int i=0; i<depth; ++i )
1784 void DoLineBreak() {
1785 buffer += lineBreak;
1789 bool simpleTextPrint;
1790 TIXML_STRING buffer;
1791 TIXML_STRING indent;
1792 TIXML_STRING lineBreak;
1797 #pragma warning( pop )