2 www.sourceforge.net/projects/tinyxml
3 Original code (2.0 and earlier )copyright (c) 2000-2002 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 )
51 #define TIXML_STRING std::string
52 #define TIXML_ISTREAM std::istream
53 #define TIXML_OSTREAM std::ostream
56 #define TIXML_STRING TiXmlString
57 #define TIXML_OSTREAM TiXmlOutStream
60 // Deprecated library function hell. Compilers want to use the
61 // new safe versions. This probably doesn't fully address the problem,
62 // but it gets closer. There are too many compilers for me to fully
63 // test. If you get compilation troubles, undefine TIXML_SAFE
65 #define TIXML_SAFE // TinyXml isn't fully buffer overrun protected, safe code. This is work in progress.
67 #if defined(_MSC_VER) && (_MSC_VER >= 1400 )
68 // Microsoft visual studio, version 2005 and higher.
69 #define TIXML_SNPRINTF _snprintf_s
70 #define TIXML_SNSCANF _snscanf_s
71 #elif defined(_MSC_VER) && (_MSC_VER >= 1200 )
72 // Microsoft visual studio, version 6 and higher.
73 //#pragma message( "Using _sn* functions." )
74 #define TIXML_SNPRINTF _snprintf
75 #define TIXML_SNSCANF _snscanf
76 #elif defined(__GNUC__) && (__GNUC__ >= 3 )
77 // GCC version 3 and higher.s
78 //#warning( "Using sn* functions." )
79 #define TIXML_SNPRINTF snprintf
80 #define TIXML_SNSCANF snscanf
90 class TiXmlDeclaration
;
91 class TiXmlParsingData
;
93 const int TIXML_MAJOR_VERSION
= 2;
94 const int TIXML_MINOR_VERSION
= 4;
95 const int TIXML_PATCH_VERSION
= 3;
97 /* Internal structure for tracking location of items
102 TiXmlCursor() { Clear(); }
103 void Clear() { row
= col
= -1; }
110 // Only used by Attribute::Query functions
119 // Used by the parsing routines.
122 TIXML_ENCODING_UNKNOWN
,
124 TIXML_ENCODING_LEGACY
127 const TiXmlEncoding TIXML_DEFAULT_ENCODING
= TIXML_ENCODING_UNKNOWN
;
129 /** TiXmlBase is a base class for every class in TinyXml.
130 It does little except to establish that TinyXml classes
131 can be printed and provide some utility functions.
133 In XML, the document and elements can contain
134 other elements and other types of nodes.
137 A Document can contain: Element (container or leaf)
142 An Element can contain: Element (container or leaf)
144 Attributes (not on tree)
148 A Decleration contains: Attributes (not on tree)
153 friend class TiXmlNode
;
154 friend class TiXmlElement
;
155 friend class TiXmlDocument
;
158 TiXmlBase() : userData(0) {}
159 virtual ~TiXmlBase() {}
161 /** All TinyXml classes can print themselves to a filestream.
162 This is a formatted print, and will insert tabs and newlines.
164 (For an unformatted stream, use the << operator.)
166 virtual void Print( FILE* cfile
, int depth
) const = 0;
168 /** The world does not agree on whether white space should be kept or
169 not. In order to make everyone happy, these global, static functions
170 are provided to set whether or not TinyXml will condense all white space
171 into a single space or not. The default is to condense. Note changing this
172 values is not thread safe.
174 static void SetCondenseWhiteSpace( bool condense
) { condenseWhiteSpace
= condense
; }
176 /// Return the current white space setting.
177 static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace
; }
179 /** Return the position, in the original source file, of this node or attribute.
180 The row and column are 1-based. (That is the first row and first column is
181 1,1). If the returns values are 0 or less, then the parser does not have
182 a row and column value.
184 Generally, the row and column value will be set when the TiXmlDocument::Load(),
185 TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set
186 when the DOM was created from operator>>.
188 The values reflect the initial load. Once the DOM is modified programmatically
189 (by adding or changing nodes and attributes) the new values will NOT update to
190 reflect changes in the document.
192 There is a minor performance cost to computing the row and column. Computation
193 can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value.
195 @sa TiXmlDocument::SetTabSize()
197 int Row() const { return location
.row
+ 1; }
198 int Column() const { return location
.col
+ 1; } ///< See Row()
200 void SetUserData( void* user
) { userData
= user
; }
201 void* GetUserData() { return userData
; }
203 // Table that returs, for a given lead byte, the total number of bytes
204 // in the UTF-8 sequence.
205 static const int utf8ByteTable
[256];
207 virtual const char* Parse( const char* p
,
208 TiXmlParsingData
* data
,
209 TiXmlEncoding encoding
/*= TIXML_ENCODING_UNKNOWN */ ) = 0;
215 TIXML_ERROR_OPENING_FILE
,
216 TIXML_ERROR_OUT_OF_MEMORY
,
217 TIXML_ERROR_PARSING_ELEMENT
,
218 TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME
,
219 TIXML_ERROR_READING_ELEMENT_VALUE
,
220 TIXML_ERROR_READING_ATTRIBUTES
,
221 TIXML_ERROR_PARSING_EMPTY
,
222 TIXML_ERROR_READING_END_TAG
,
223 TIXML_ERROR_PARSING_UNKNOWN
,
224 TIXML_ERROR_PARSING_COMMENT
,
225 TIXML_ERROR_PARSING_DECLARATION
,
226 TIXML_ERROR_DOCUMENT_EMPTY
,
227 TIXML_ERROR_EMBEDDED_NULL
,
228 TIXML_ERROR_PARSING_CDATA
,
230 TIXML_ERROR_STRING_COUNT
235 // See STL_STRING_BUG
236 // Utility class to overcome a bug.
240 StringToBuffer( const TIXML_STRING
& str
);
245 static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding
);
246 inline static bool IsWhiteSpace( char c
)
248 return ( isspace( (unsigned char) c
) || c
== '\n' || c
== '\r' );
250 inline static bool IsWhiteSpace( int c
)
253 return IsWhiteSpace( (char) c
);
254 return false; // Again, only truly correct for English/Latin...but usually works.
257 virtual void StreamOut (TIXML_OSTREAM
*) const = 0;
260 static bool StreamWhiteSpace( TIXML_ISTREAM
* in
, TIXML_STRING
* tag
);
261 static bool StreamTo( TIXML_ISTREAM
* in
, int character
, TIXML_STRING
* tag
);
264 /* Reads an XML name into the string provided. Returns
265 a pointer just past the last character of the name,
266 or 0 if the function has an error.
268 static const char* ReadName( const char* p
, TIXML_STRING
* name
, TiXmlEncoding encoding
);
270 /* Reads text. Returns a pointer past the given end tag.
271 Wickedly complex options, but it keeps the (sensitive) code in one place.
273 static const char* ReadText( const char* in
, // where to start
274 TIXML_STRING
* text
, // the string read
275 bool ignoreWhiteSpace
, // whether to keep the white space
276 const char* endTag
, // what ends this text
277 bool ignoreCase
, // whether to ignore case in the end tag
278 TiXmlEncoding encoding
); // the current encoding
280 // If an entity has been found, transform it into a character.
281 static const char* GetEntity( const char* in
, char* value
, int* length
, TiXmlEncoding encoding
);
283 // Get a character, while interpreting entities.
284 // The length can be from 0 to 4 bytes.
285 inline static const char* GetChar( const char* p
, char* _value
, int* length
, TiXmlEncoding encoding
)
288 if ( encoding
== TIXML_ENCODING_UTF8
)
290 *length
= utf8ByteTable
[ *((unsigned char*)p
) ];
291 assert( *length
>= 0 && *length
< 5 );
301 return GetEntity( p
, _value
, length
, encoding
);
307 //strncpy( _value, p, *length ); // lots of compilers don't like this function (unsafe),
308 // and the null terminator isn't needed
309 for( int i
=0; p
[i
] && i
<*length
; ++i
) {
312 return p
+ (*length
);
321 // Puts a string to a stream, expanding entities as it goes.
322 // Note this should not contian the '<', '>', etc, or they will be transformed into entities!
323 static void PutString( const TIXML_STRING
& str
, TIXML_OSTREAM
* out
);
325 static void PutString( const TIXML_STRING
& str
, TIXML_STRING
* out
);
327 // Return true if the next characters in the stream are any of the endTag sequences.
328 // Ignore case only works for english, and should only be relied on when comparing
329 // to English words: StringEqual( p, "version", true ) is fine.
330 static bool StringEqual( const char* p
,
333 TiXmlEncoding encoding
);
335 static const char* errorString
[ TIXML_ERROR_STRING_COUNT
];
337 TiXmlCursor location
;
339 /// Field containing a generic user pointer
342 // None of these methods are reliable for any language except English.
343 // Good for approximation, not great for accuracy.
344 static int IsAlpha( unsigned char anyByte
, TiXmlEncoding encoding
);
345 static int IsAlphaNum( unsigned char anyByte
, TiXmlEncoding encoding
);
346 inline static int ToLower( int v
, TiXmlEncoding encoding
)
348 if ( encoding
== TIXML_ENCODING_UTF8
)
350 if ( v
< 128 ) return tolower( v
);
358 static void ConvertUTF32ToUTF8( unsigned long input
, char* output
, int* length
);
361 TiXmlBase( const TiXmlBase
& ); // not implemented.
362 void operator=( const TiXmlBase
& base
); // not allowed.
367 unsigned int strLength
;
373 MAX_ENTITY_LENGTH
= 6
376 static Entity entity
[ NUM_ENTITY
];
377 static bool condenseWhiteSpace
;
381 /** The parent class for everything in the Document Object Model.
382 (Except for attributes).
383 Nodes have siblings, a parent, and children. A node can be
384 in a document, or stand on its own. The type of a TiXmlNode
385 can be queried, and it can be cast to its more defined type.
387 class TiXmlNode
: public TiXmlBase
389 friend class TiXmlDocument
;
390 friend class TiXmlElement
;
395 /** An input stream operator, for every class. Tolerant of newlines and
396 formatting, but doesn't expect them.
398 friend std::istream
& operator >> (std::istream
& in
, TiXmlNode
& base
);
400 /** An output stream operator, for every class. Note that this outputs
401 without any newlines or formatting, as opposed to Print(), which
402 includes tabs and new lines.
404 The operator<< and operator>> are not completely symmetric. Writing
405 a node to a stream is very well defined. You'll get a nice stream
406 of output, without any extra whitespace or newlines.
408 But reading is not as well defined. (As it always is.) If you create
409 a TiXmlElement (for example) and read that from an input stream,
410 the text needs to define an element or junk will result. This is
411 true of all input streams, but it's worth keeping in mind.
413 A TiXmlDocument will read nodes until it reads a root element, and
414 all the children of that root element.
416 friend std::ostream
& operator<< (std::ostream
& out
, const TiXmlNode
& base
);
418 /// Appends the XML node or attribute to a std::string.
419 friend std::string
& operator<< (std::string
& out
, const TiXmlNode
& base
);
422 // Used internally, not part of the public API.
423 friend TIXML_OSTREAM
& operator<< (TIXML_OSTREAM
& out
, const TiXmlNode
& base
);
426 /** The types of XML nodes supported by TinyXml. (All the
427 unsupported types are picked up by UNKNOWN.)
440 virtual ~TiXmlNode();
442 /** The meaning of 'value' changes for the specific type of
445 Document: filename of the xml file
446 Element: name of the element
447 Comment: the comment text
448 Unknown: the tag contents
449 Text: the text string
452 The subclasses will wrap this function.
454 const char *Value() const { return value
.c_str (); }
457 /** Return Value() as a std::string. If you only use STL,
458 this is more efficient than calling Value().
459 Only available in STL mode.
461 const std::string
& ValueStr() const { return value
; }
464 /** Changes the value of the node. Defined as:
466 Document: filename of the xml file
467 Element: name of the element
468 Comment: the comment text
469 Unknown: the tag contents
470 Text: the text string
473 void SetValue(const char * _value
) { value
= _value
;}
476 /// STL std::string form.
477 void SetValue( const std::string
& _value
) { value
= _value
; }
480 /// Delete all the children of this node. Does not affect 'this'.
483 /// One step up the DOM.
484 TiXmlNode
* Parent() { return parent
; }
485 const TiXmlNode
* Parent() const { return parent
; }
487 const TiXmlNode
* FirstChild() const { return firstChild
; } ///< The first child of this node. Will be null if there are no children.
488 TiXmlNode
* FirstChild() { return firstChild
; }
489 const TiXmlNode
* FirstChild( const char * value
) const; ///< The first child of this node with the matching 'value'. Will be null if none found.
490 TiXmlNode
* FirstChild( const char * value
); ///< The first child of this node with the matching 'value'. Will be null if none found.
492 const TiXmlNode
* LastChild() const { return lastChild
; } /// The last child of this node. Will be null if there are no children.
493 TiXmlNode
* LastChild() { return lastChild
; }
494 const TiXmlNode
* LastChild( const char * value
) const; /// The last child of this node matching 'value'. Will be null if there are no children.
495 TiXmlNode
* LastChild( const char * value
);
498 const TiXmlNode
* FirstChild( const std::string
& _value
) const { return FirstChild (_value
.c_str ()); } ///< STL std::string form.
499 TiXmlNode
* FirstChild( const std::string
& _value
) { return FirstChild (_value
.c_str ()); } ///< STL std::string form.
500 const TiXmlNode
* LastChild( const std::string
& _value
) const { return LastChild (_value
.c_str ()); } ///< STL std::string form.
501 TiXmlNode
* LastChild( const std::string
& _value
) { return LastChild (_value
.c_str ()); } ///< STL std::string form.
504 /** An alternate way to walk the children of a node.
505 One way to iterate over nodes is:
507 for( child = parent->FirstChild(); child; child = child->NextSibling() )
510 IterateChildren does the same thing with the syntax:
513 while( child = parent->IterateChildren( child ) )
516 IterateChildren takes the previous child as input and finds
517 the next one. If the previous child is null, it returns the
518 first. IterateChildren will return null when done.
520 const TiXmlNode
* IterateChildren( const TiXmlNode
* previous
) const;
521 TiXmlNode
* IterateChildren( TiXmlNode
* previous
);
523 /// This flavor of IterateChildren searches for children with a particular 'value'
524 const TiXmlNode
* IterateChildren( const char * value
, const TiXmlNode
* previous
) const;
525 TiXmlNode
* IterateChildren( const char * value
, TiXmlNode
* previous
);
528 const TiXmlNode
* IterateChildren( const std::string
& _value
, const TiXmlNode
* previous
) const { return IterateChildren (_value
.c_str (), previous
); } ///< STL std::string form.
529 TiXmlNode
* IterateChildren( const std::string
& _value
, TiXmlNode
* previous
) { return IterateChildren (_value
.c_str (), previous
); } ///< STL std::string form.
532 /** Add a new node related to this. Adds a child past the LastChild.
533 Returns a pointer to the new object or NULL if an error occured.
535 TiXmlNode
* InsertEndChild( const TiXmlNode
& addThis
);
538 /** Add a new node related to this. Adds a child past the LastChild.
540 NOTE: the node to be added is passed by pointer, and will be
541 henceforth owned (and deleted) by tinyXml. This method is efficient
542 and avoids an extra copy, but should be used with care as it
543 uses a different memory model than the other insert functions.
547 TiXmlNode
* LinkEndChild( TiXmlNode
* addThis
);
549 /** Add a new node related to this. Adds a child before the specified child.
550 Returns a pointer to the new object or NULL if an error occured.
552 TiXmlNode
* InsertBeforeChild( TiXmlNode
* beforeThis
, const TiXmlNode
& addThis
);
554 /** Add a new node related to this. Adds a child after the specified child.
555 Returns a pointer to the new object or NULL if an error occured.
557 TiXmlNode
* InsertAfterChild( TiXmlNode
* afterThis
, const TiXmlNode
& addThis
);
559 /** Replace a child of this node.
560 Returns a pointer to the new object or NULL if an error occured.
562 TiXmlNode
* ReplaceChild( TiXmlNode
* replaceThis
, const TiXmlNode
& withThis
);
564 /// Delete a child of this node.
565 bool RemoveChild( TiXmlNode
* removeThis
);
567 /// Navigate to a sibling node.
568 const TiXmlNode
* PreviousSibling() const { return prev
; }
569 TiXmlNode
* PreviousSibling() { return prev
; }
571 /// Navigate to a sibling node.
572 const TiXmlNode
* PreviousSibling( const char * ) const;
573 TiXmlNode
* PreviousSibling( const char * );
576 const TiXmlNode
* PreviousSibling( const std::string
& _value
) const { return PreviousSibling (_value
.c_str ()); } ///< STL std::string form.
577 TiXmlNode
* PreviousSibling( const std::string
& _value
) { return PreviousSibling (_value
.c_str ()); } ///< STL std::string form.
578 const TiXmlNode
* NextSibling( const std::string
& _value
) const { return NextSibling (_value
.c_str ()); } ///< STL std::string form.
579 TiXmlNode
* NextSibling( const std::string
& _value
) { return NextSibling (_value
.c_str ()); } ///< STL std::string form.
582 /// Navigate to a sibling node.
583 const TiXmlNode
* NextSibling() const { return next
; }
584 TiXmlNode
* NextSibling() { return next
; }
586 /// Navigate to a sibling node with the given 'value'.
587 const TiXmlNode
* NextSibling( const char * ) const;
588 TiXmlNode
* NextSibling( const char * );
590 /** Convenience function to get through elements.
591 Calls NextSibling and ToElement. Will skip all non-Element
592 nodes. Returns 0 if there is not another element.
594 const TiXmlElement
* NextSiblingElement() const;
595 TiXmlElement
* NextSiblingElement();
597 /** Convenience function to get through elements.
598 Calls NextSibling and ToElement. Will skip all non-Element
599 nodes. Returns 0 if there is not another element.
601 const TiXmlElement
* NextSiblingElement( const char * ) const;
602 TiXmlElement
* NextSiblingElement( const char * );
605 const TiXmlElement
* NextSiblingElement( const std::string
& _value
) const { return NextSiblingElement (_value
.c_str ()); } ///< STL std::string form.
606 TiXmlElement
* NextSiblingElement( const std::string
& _value
) { return NextSiblingElement (_value
.c_str ()); } ///< STL std::string form.
609 /// Convenience function to get through elements.
610 const TiXmlElement
* FirstChildElement() const;
611 TiXmlElement
* FirstChildElement();
613 /// Convenience function to get through elements.
614 const TiXmlElement
* FirstChildElement( const char * value
) const;
615 TiXmlElement
* FirstChildElement( const char * value
);
618 const TiXmlElement
* FirstChildElement( const std::string
& _value
) const { return FirstChildElement (_value
.c_str ()); } ///< STL std::string form.
619 TiXmlElement
* FirstChildElement( const std::string
& _value
) { return FirstChildElement (_value
.c_str ()); } ///< STL std::string form.
622 /** Query the type (as an enumerated value, above) of this node.
623 The possible types are: DOCUMENT, ELEMENT, COMMENT,
624 UNKNOWN, TEXT, and DECLARATION.
626 int Type() const { return type
; }
628 /** Return a pointer to the Document this node lives in.
629 Returns null if not in a document.
631 const TiXmlDocument
* GetDocument() const;
632 TiXmlDocument
* GetDocument();
634 /// Returns true if this node has no children.
635 bool NoChildren() const { return !firstChild
; }
637 virtual const TiXmlDocument
* ToDocument() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
638 virtual const TiXmlElement
* ToElement() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
639 virtual const TiXmlComment
* ToComment() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
640 virtual const TiXmlUnknown
* ToUnknown() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
641 virtual const TiXmlText
* ToText() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
642 virtual const TiXmlDeclaration
* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
644 virtual TiXmlDocument
* ToDocument() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
645 virtual TiXmlElement
* ToElement() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
646 virtual TiXmlComment
* ToComment() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
647 virtual TiXmlUnknown
* ToUnknown() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
648 virtual TiXmlText
* ToText() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
649 virtual TiXmlDeclaration
* ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
651 /** Create an exact duplicate of this node and return it. The memory must be deleted
654 virtual TiXmlNode
* Clone() const = 0;
657 TiXmlNode( NodeType _type
);
659 // Copy to the allocated object. Shared functionality between Clone, Copy constructor,
660 // and the assignment operator.
661 void CopyTo( TiXmlNode
* target
) const;
664 // The real work of the input operator.
665 virtual void StreamIn( TIXML_ISTREAM
* in
, TIXML_STRING
* tag
) = 0;
668 // Figure out what is at *p, and parse it. Returns null if it is not an xml node.
669 TiXmlNode
* Identify( const char* start
, TiXmlEncoding encoding
);
674 TiXmlNode
* firstChild
;
675 TiXmlNode
* lastChild
;
683 TiXmlNode( const TiXmlNode
& ); // not implemented.
684 void operator=( const TiXmlNode
& base
); // not allowed.
688 /** An attribute is a name-value pair. Elements have an arbitrary
689 number of attributes, each with a unique name.
691 @note The attributes are not TiXmlNodes, since they are not
692 part of the tinyXML document object model. There are other
693 suggested ways to look at this problem.
695 class TiXmlAttribute
: public TiXmlBase
697 friend class TiXmlAttributeSet
;
700 /// Construct an empty attribute.
701 TiXmlAttribute() : TiXmlBase()
708 /// std::string constructor.
709 TiXmlAttribute( const std::string
& _name
, const std::string
& _value
)
718 /// Construct an attribute with a name and value.
719 TiXmlAttribute( const char * _name
, const char * _value
)
727 const char* Name() const { return name
.c_str (); } ///< Return the name of this attribute.
728 const char* Value() const { return value
.c_str (); } ///< Return the value of this attribute.
729 int IntValue() const; ///< Return the value of this attribute, converted to an integer.
730 double DoubleValue() const; ///< Return the value of this attribute, converted to a double.
732 // Get the tinyxml string representation
733 const TIXML_STRING
& NameTStr() const { return name
; }
735 /** QueryIntValue examines the value string. It is an alternative to the
736 IntValue() method with richer error checking.
737 If the value is an integer, it is stored in 'value' and
738 the call returns TIXML_SUCCESS. If it is not
739 an integer, it returns TIXML_WRONG_TYPE.
741 A specialized but useful call. Note that for success it returns 0,
742 which is the opposite of almost all other TinyXml calls.
744 int QueryIntValue( int* _value
) const;
745 /// QueryDoubleValue examines the value string. See QueryIntValue().
746 int QueryDoubleValue( double* _value
) const;
748 void SetName( const char* _name
) { name
= _name
; } ///< Set the name of this attribute.
749 void SetValue( const char* _value
) { value
= _value
; } ///< Set the value.
751 void SetIntValue( int _value
); ///< Set the value from an integer.
752 void SetDoubleValue( double _value
); ///< Set the value from a double.
755 /// STL std::string form.
756 void SetName( const std::string
& _name
) { name
= _name
; }
757 /// STL std::string form.
758 void SetValue( const std::string
& _value
) { value
= _value
; }
761 /// Get the next sibling attribute in the DOM. Returns null at end.
762 const TiXmlAttribute
* Next() const;
763 TiXmlAttribute
* Next();
764 /// Get the previous sibling attribute in the DOM. Returns null at beginning.
765 const TiXmlAttribute
* Previous() const;
766 TiXmlAttribute
* Previous();
768 bool operator==( const TiXmlAttribute
& rhs
) const { return rhs
.name
== name
; }
769 bool operator<( const TiXmlAttribute
& rhs
) const { return name
< rhs
.name
; }
770 bool operator>( const TiXmlAttribute
& rhs
) const { return name
> rhs
.name
; }
772 /* Attribute parsing starts: first letter of the name
773 returns: the next char after the value end quote
775 virtual const char* Parse( const char* p
, TiXmlParsingData
* data
, TiXmlEncoding encoding
);
777 // Prints this Attribute to a FILE stream.
778 virtual void Print( FILE* cfile
, int depth
) const;
780 virtual void StreamOut( TIXML_OSTREAM
* out
) const;
782 // Set the document pointer so the attribute can report errors.
783 void SetDocument( TiXmlDocument
* doc
) { document
= doc
; }
786 TiXmlAttribute( const TiXmlAttribute
& ); // not implemented.
787 void operator=( const TiXmlAttribute
& base
); // not allowed.
789 TiXmlDocument
* document
; // A pointer back to a document, for error reporting.
792 TiXmlAttribute
* prev
;
793 TiXmlAttribute
* next
;
797 /* A class used to manage a group of attributes.
798 It is only used internally, both by the ELEMENT and the DECLARATION.
800 The set can be changed transparent to the Element and Declaration
801 classes that use it, but NOT transparent to the Attribute
802 which has to implement a next() and previous() method. Which makes
803 it a bit problematic and prevents the use of STL.
805 This version is implemented with circular lists because:
806 - I like circular lists
807 - it demonstrates some independence from the (typical) doubly linked list.
809 class TiXmlAttributeSet
813 ~TiXmlAttributeSet();
815 void Add( TiXmlAttribute
* attribute
);
816 void Remove( TiXmlAttribute
* attribute
);
818 const TiXmlAttribute
* First() const { return ( sentinel
.next
== &sentinel
) ? 0 : sentinel
.next
; }
819 TiXmlAttribute
* First() { return ( sentinel
.next
== &sentinel
) ? 0 : sentinel
.next
; }
820 const TiXmlAttribute
* Last() const { return ( sentinel
.prev
== &sentinel
) ? 0 : sentinel
.prev
; }
821 TiXmlAttribute
* Last() { return ( sentinel
.prev
== &sentinel
) ? 0 : sentinel
.prev
; }
823 const TiXmlAttribute
* Find( const TIXML_STRING
& name
) const;
824 TiXmlAttribute
* Find( const TIXML_STRING
& name
);
827 //*ME: Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element),
828 //*ME: this class must be also use a hidden/disabled copy-constructor !!!
829 TiXmlAttributeSet( const TiXmlAttributeSet
& ); // not allowed
830 void operator=( const TiXmlAttributeSet
& ); // not allowed (as TiXmlAttribute)
832 TiXmlAttribute sentinel
;
836 /** The element is a container class. It has a value, the element name,
837 and can contain other elements, text, comments, and unknowns.
838 Elements also contain an arbitrary number of attributes.
840 class TiXmlElement
: public TiXmlNode
843 /// Construct an element.
844 TiXmlElement (const char * in_value
);
847 /// std::string constructor.
848 TiXmlElement( const std::string
& _value
);
851 TiXmlElement( const TiXmlElement
& );
853 void operator=( const TiXmlElement
& base
);
855 virtual ~TiXmlElement();
857 /** Given an attribute name, Attribute() returns the value
858 for the attribute of that name, or null if none exists.
860 const char* Attribute( const char* name
) const;
862 /** Given an attribute name, Attribute() returns the value
863 for the attribute of that name, or null if none exists.
864 If the attribute exists and can be converted to an integer,
865 the integer value will be put in the return 'i', if 'i'
868 const char* Attribute( const char* name
, int* i
) const;
870 /** Given an attribute name, Attribute() returns the value
871 for the attribute of that name, or null if none exists.
872 If the attribute exists and can be converted to an double,
873 the double value will be put in the return 'd', if 'd'
876 const char* Attribute( const char* name
, double* d
) const;
878 /** QueryIntAttribute examines the attribute - it is an alternative to the
879 Attribute() method with richer error checking.
880 If the attribute is an integer, it is stored in 'value' and
881 the call returns TIXML_SUCCESS. If it is not
882 an integer, it returns TIXML_WRONG_TYPE. If the attribute
883 does not exist, then TIXML_NO_ATTRIBUTE is returned.
885 int QueryIntAttribute( const char* name
, int* _value
) const;
886 /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute().
887 int QueryDoubleAttribute( const char* name
, double* _value
) const;
888 /// QueryFloatAttribute examines the attribute - see QueryIntAttribute().
889 int QueryFloatAttribute( const char* name
, float* _value
) const {
891 int result
= QueryDoubleAttribute( name
, &d
);
892 if ( result
== TIXML_SUCCESS
) {
898 /** Sets an attribute of name to a given value. The attribute
899 will be created if it does not exist, or changed if it does.
901 void SetAttribute( const char* name
, const char * _value
);
904 const char* Attribute( const std::string
& name
) const { return Attribute( name
.c_str() ); }
905 const char* Attribute( const std::string
& name
, int* i
) const { return Attribute( name
.c_str(), i
); }
906 const char* Attribute( const std::string
& name
, double* d
) const { return Attribute( name
.c_str(), d
); }
907 int QueryIntAttribute( const std::string
& name
, int* _value
) const { return QueryIntAttribute( name
.c_str(), _value
); }
908 int QueryDoubleAttribute( const std::string
& name
, double* _value
) const { return QueryDoubleAttribute( name
.c_str(), _value
); }
910 /// STL std::string form.
911 void SetAttribute( const std::string
& name
, const std::string
& _value
);
912 ///< STL std::string form.
913 void SetAttribute( const std::string
& name
, int _value
);
916 /** Sets an attribute of name to a given value. The attribute
917 will be created if it does not exist, or changed if it does.
919 void SetAttribute( const char * name
, int value
);
921 /** Sets an attribute of name to a given value. The attribute
922 will be created if it does not exist, or changed if it does.
924 void SetDoubleAttribute( const char * name
, double value
);
926 /** Deletes an attribute with the given name.
928 void RemoveAttribute( const char * name
);
930 void RemoveAttribute( const std::string
& name
) { RemoveAttribute (name
.c_str ()); } ///< STL std::string form.
933 const TiXmlAttribute
* FirstAttribute() const { return attributeSet
.First(); } ///< Access the first attribute in this element.
934 TiXmlAttribute
* FirstAttribute() { return attributeSet
.First(); }
935 const TiXmlAttribute
* LastAttribute() const { return attributeSet
.Last(); } ///< Access the last attribute in this element.
936 TiXmlAttribute
* LastAttribute() { return attributeSet
.Last(); }
938 /** Convenience function for easy access to the text inside an element. Although easy
939 and concise, GetText() is limited compared to getting the TiXmlText child
940 and accessing it directly.
942 If the first child of 'this' is a TiXmlText, the GetText()
943 returns the character string of the Text node, else null is returned.
945 This is a convenient method for getting the text of simple contained text:
947 <foo>This is text</foo>
948 const char* str = fooElement->GetText();
951 'str' will be a pointer to "This is text".
953 Note that this function can be misleading. If the element foo was created from
956 <foo><b>This is text</b></foo>
959 then the value of str would be null. The first child node isn't a text node, it is
960 another element. From this XML:
962 <foo>This is <b>text</b></foo>
964 GetText() will return "This is ".
966 WARNING: GetText() accesses a child node - don't become confused with the
967 similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are
968 safe type casts on the referenced node.
970 const char* GetText() const;
972 /// Creates a new Element and returns it - the returned element is a copy.
973 virtual TiXmlNode
* Clone() const;
974 // Print the Element to a FILE stream.
975 virtual void Print( FILE* cfile
, int depth
) const;
977 /* Attribtue parsing starts: next char past '<'
978 returns: next char past '>'
980 virtual const char* Parse( const char* p
, TiXmlParsingData
* data
, TiXmlEncoding encoding
);
982 virtual const TiXmlElement
* ToElement() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
983 virtual TiXmlElement
* ToElement() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
987 void CopyTo( TiXmlElement
* target
) const;
988 void ClearThis(); // like clear, but initializes 'this' object as well
990 // Used to be public [internal use]
992 virtual void StreamIn( TIXML_ISTREAM
* in
, TIXML_STRING
* tag
);
994 virtual void StreamOut( TIXML_OSTREAM
* out
) const;
997 Reads the "value" of the element -- another element, or text.
998 This should terminate with the current end tag.
1000 const char* ReadValue( const char* in
, TiXmlParsingData
* prevData
, TiXmlEncoding encoding
);
1004 TiXmlAttributeSet attributeSet
;
1010 class TiXmlComment
: public TiXmlNode
1013 /// Constructs an empty comment.
1014 TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT
) {}
1015 TiXmlComment( const TiXmlComment
& );
1016 void operator=( const TiXmlComment
& base
);
1018 virtual ~TiXmlComment() {}
1020 /// Returns a copy of this Comment.
1021 virtual TiXmlNode
* Clone() const;
1022 /// Write this Comment to a FILE stream.
1023 virtual void Print( FILE* cfile
, int depth
) const;
1025 /* Attribtue parsing starts: at the ! of the !--
1026 returns: next char past '>'
1028 virtual const char* Parse( const char* p
, TiXmlParsingData
* data
, TiXmlEncoding encoding
);
1030 virtual const TiXmlComment
* ToComment() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1031 virtual TiXmlComment
* ToComment() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1034 void CopyTo( TiXmlComment
* target
) const;
1036 // used to be public
1037 #ifdef TIXML_USE_STL
1038 virtual void StreamIn( TIXML_ISTREAM
* in
, TIXML_STRING
* tag
);
1040 virtual void StreamOut( TIXML_OSTREAM
* out
) const;
1047 /** XML text. A text node can have 2 ways to output the next. "normal" output
1048 and CDATA. It will default to the mode it was parsed from the XML file and
1049 you generally want to leave it alone, but you can change the output mode with
1050 SetCDATA() and query it with CDATA().
1052 class TiXmlText
: public TiXmlNode
1054 friend class TiXmlElement
;
1056 /** Constructor for text element. By default, it is treated as
1057 normal, encoded text. If you want it be output as a CDATA text
1058 element, set the parameter _cdata to 'true'
1060 TiXmlText (const char * initValue
) : TiXmlNode (TiXmlNode::TEXT
)
1062 SetValue( initValue
);
1065 virtual ~TiXmlText() {}
1067 #ifdef TIXML_USE_STL
1069 TiXmlText( const std::string
& initValue
) : TiXmlNode (TiXmlNode::TEXT
)
1071 SetValue( initValue
);
1076 TiXmlText( const TiXmlText
& copy
) : TiXmlNode( TiXmlNode::TEXT
) { copy
.CopyTo( this ); }
1077 void operator=( const TiXmlText
& base
) { base
.CopyTo( this ); }
1079 /// Write this text object to a FILE stream.
1080 virtual void Print( FILE* cfile
, int depth
) const;
1082 /// Queries whether this represents text using a CDATA section.
1083 bool CDATA() { return cdata
; }
1084 /// Turns on or off a CDATA representation of text.
1085 void SetCDATA( bool _cdata
) { cdata
= _cdata
; }
1087 virtual const char* Parse( const char* p
, TiXmlParsingData
* data
, TiXmlEncoding encoding
);
1089 virtual const TiXmlText
* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1090 virtual TiXmlText
* ToText() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1093 /// [internal use] Creates a new Element and returns it.
1094 virtual TiXmlNode
* Clone() const;
1095 void CopyTo( TiXmlText
* target
) const;
1097 virtual void StreamOut ( TIXML_OSTREAM
* out
) const;
1098 bool Blank() const; // returns true if all white space and new lines
1100 #ifdef TIXML_USE_STL
1101 virtual void StreamIn( TIXML_ISTREAM
* in
, TIXML_STRING
* tag
);
1105 bool cdata
; // true if this should be input and output as a CDATA style text element
1109 /** In correct XML the declaration is the first entry in the file.
1111 <?xml version="1.0" standalone="yes"?>
1114 TinyXml will happily read or write files without a declaration,
1115 however. There are 3 possible attributes to the declaration:
1116 version, encoding, and standalone.
1118 Note: In this version of the code, the attributes are
1119 handled as special cases, not generic attributes, simply
1120 because there can only be at most 3 and they are always the same.
1122 class TiXmlDeclaration
: public TiXmlNode
1125 /// Construct an empty declaration.
1126 TiXmlDeclaration() : TiXmlNode( TiXmlNode::DECLARATION
) {}
1128 #ifdef TIXML_USE_STL
1130 TiXmlDeclaration( const std::string
& _version
,
1131 const std::string
& _encoding
,
1132 const std::string
& _standalone
);
1136 TiXmlDeclaration( const char* _version
,
1137 const char* _encoding
,
1138 const char* _standalone
);
1140 TiXmlDeclaration( const TiXmlDeclaration
& copy
);
1141 void operator=( const TiXmlDeclaration
& copy
);
1143 virtual ~TiXmlDeclaration() {}
1145 /// Version. Will return an empty string if none was found.
1146 const char *Version() const { return version
.c_str (); }
1147 /// Encoding. Will return an empty string if none was found.
1148 const char *Encoding() const { return encoding
.c_str (); }
1149 /// Is this a standalone document?
1150 const char *Standalone() const { return standalone
.c_str (); }
1152 /// Creates a copy of this Declaration and returns it.
1153 virtual TiXmlNode
* Clone() const;
1154 /// Print this declaration to a FILE stream.
1155 virtual void Print( FILE* cfile
, int depth
) const;
1157 virtual const char* Parse( const char* p
, TiXmlParsingData
* data
, TiXmlEncoding encoding
);
1159 virtual const TiXmlDeclaration
* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1160 virtual TiXmlDeclaration
* ToDeclaration() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1163 void CopyTo( TiXmlDeclaration
* target
) const;
1164 // used to be public
1165 #ifdef TIXML_USE_STL
1166 virtual void StreamIn( TIXML_ISTREAM
* in
, TIXML_STRING
* tag
);
1168 virtual void StreamOut ( TIXML_OSTREAM
* out
) const;
1172 TIXML_STRING version
;
1173 TIXML_STRING encoding
;
1174 TIXML_STRING standalone
;
1178 /** Any tag that tinyXml doesn't recognize is saved as an
1179 unknown. It is a tag of text, but should not be modified.
1180 It will be written back to the XML, unchanged, when the file
1183 DTD tags get thrown into TiXmlUnknowns.
1185 class TiXmlUnknown
: public TiXmlNode
1188 TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN
) {}
1189 virtual ~TiXmlUnknown() {}
1191 TiXmlUnknown( const TiXmlUnknown
& copy
) : TiXmlNode( TiXmlNode::UNKNOWN
) { copy
.CopyTo( this ); }
1192 void operator=( const TiXmlUnknown
& copy
) { copy
.CopyTo( this ); }
1194 /// Creates a copy of this Unknown and returns it.
1195 virtual TiXmlNode
* Clone() const;
1196 /// Print this Unknown to a FILE stream.
1197 virtual void Print( FILE* cfile
, int depth
) const;
1199 virtual const char* Parse( const char* p
, TiXmlParsingData
* data
, TiXmlEncoding encoding
);
1201 virtual const TiXmlUnknown
* ToUnknown() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1202 virtual TiXmlUnknown
* ToUnknown() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1205 void CopyTo( TiXmlUnknown
* target
) const;
1207 #ifdef TIXML_USE_STL
1208 virtual void StreamIn( TIXML_ISTREAM
* in
, TIXML_STRING
* tag
);
1210 virtual void StreamOut ( TIXML_OSTREAM
* out
) const;
1217 /** Always the top level node. A document binds together all the
1218 XML pieces. It can be saved, loaded, and printed to the screen.
1219 The 'value' of a document node is the xml file name.
1221 class TiXmlDocument
: public TiXmlNode
1224 /// Create an empty document, that has no name.
1226 /// Create a document with a name. The name of the document is also the filename of the xml.
1227 TiXmlDocument( const char * documentName
);
1229 #ifdef TIXML_USE_STL
1231 TiXmlDocument( const std::string
& documentName
);
1234 TiXmlDocument( const TiXmlDocument
& copy
);
1235 void operator=( const TiXmlDocument
& copy
);
1237 virtual ~TiXmlDocument() {}
1239 /** Load a file using the current document value.
1240 Returns true if successful. Will delete any existing
1241 document data before loading.
1243 bool LoadFile( TiXmlEncoding encoding
= TIXML_DEFAULT_ENCODING
);
1244 /// Save a file using the current document value. Returns true if successful.
1245 bool SaveFile() const;
1246 /// Load a file using the given filename. Returns true if successful.
1247 bool LoadFile( const char * filename
, TiXmlEncoding encoding
= TIXML_DEFAULT_ENCODING
);
1248 /// Save a file using the given filename. Returns true if successful.
1249 bool SaveFile( const char * filename
) const;
1250 /** Load a file using the given FILE*. Returns true if successful. Note that this method
1251 doesn't stream - the entire object pointed at by the FILE*
1252 will be interpreted as an XML file. TinyXML doesn't stream in XML from the current
1253 file location. Streaming may be added in the future.
1255 bool LoadFile( FILE*, TiXmlEncoding encoding
= TIXML_DEFAULT_ENCODING
);
1256 /// Save a file using the given FILE*. Returns true if successful.
1257 bool SaveFile( FILE* ) const;
1259 #ifdef TIXML_USE_STL
1260 bool LoadFile( const std::string
& filename
, TiXmlEncoding encoding
= TIXML_DEFAULT_ENCODING
) ///< STL std::string version.
1262 StringToBuffer
f( filename
);
1263 return ( f
.buffer
&& LoadFile( f
.buffer
, encoding
));
1265 bool SaveFile( const std::string
& filename
) const ///< STL std::string version.
1267 StringToBuffer
f( filename
);
1268 return ( f
.buffer
&& SaveFile( f
.buffer
));
1272 /** Parse the given null terminated block of xml data. Passing in an encoding to this
1273 method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml
1274 to use that encoding, regardless of what TinyXml might otherwise try to detect.
1276 virtual const char* Parse( const char* p
, TiXmlParsingData
* data
= 0, TiXmlEncoding encoding
= TIXML_DEFAULT_ENCODING
);
1278 /** Get the root element -- the only top level element -- of the document.
1279 In well formed XML, there should only be one. TinyXml is tolerant of
1280 multiple elements at the document level.
1282 const TiXmlElement
* RootElement() const { return FirstChildElement(); }
1283 TiXmlElement
* RootElement() { return FirstChildElement(); }
1285 /** If an error occurs, Error will be set to true. Also,
1286 - The ErrorId() will contain the integer identifier of the error (not generally useful)
1287 - The ErrorDesc() method will return the name of the error. (very useful)
1288 - The ErrorRow() and ErrorCol() will return the location of the error (if known)
1290 bool Error() const { return error
; }
1292 /// Contains a textual (english) description of the error if one occurs.
1293 const char * ErrorDesc() const { return errorDesc
.c_str (); }
1295 /** Generally, you probably want the error string ( ErrorDesc() ). But if you
1296 prefer the ErrorId, this function will fetch it.
1298 int ErrorId() const { return errorId
; }
1300 /** Returns the location (if known) of the error. The first column is column 1,
1301 and the first row is row 1. A value of 0 means the row and column wasn't applicable
1302 (memory errors, for example, have no row/column) or the parser lost the error. (An
1303 error in the error reporting, in that case.)
1305 @sa SetTabSize, Row, Column
1307 int ErrorRow() { return errorLocation
.row
+1; }
1308 int ErrorCol() { return errorLocation
.col
+1; } ///< The column where the error occured. See ErrorRow()
1310 /** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol())
1311 to report the correct values for row and column. It does not change the output
1312 or input in any way.
1314 By calling this method, with a tab size
1315 greater than 0, the row and column of each node and attribute is stored
1316 when the file is loaded. Very useful for tracking the DOM back in to
1319 The tab size is required for calculating the location of nodes. If not
1320 set, the default of 4 is used. The tabsize is set per document. Setting
1321 the tabsize to 0 disables row/column tracking.
1323 Note that row and column tracking is not supported when using operator>>.
1325 The tab size needs to be enabled before the parse or load. Correct usage:
1328 doc.SetTabSize( 8 );
1329 doc.Load( "myfile.xml" );
1334 void SetTabSize( int _tabsize
) { tabsize
= _tabsize
; }
1336 int TabSize() const { return tabsize
; }
1338 /** If you have handled the error, it can be reset with this call. The error
1339 state is automatically cleared if you Parse a new XML block.
1341 void ClearError() { error
= false;
1344 errorLocation
.row
= errorLocation
.col
= 0;
1345 //errorLocation.last = 0;
1348 /** Dump the document to standard out. */
1349 void Print() const { Print( stdout
, 0 ); }
1351 /// Print this Document to a FILE stream.
1352 virtual void Print( FILE* cfile
, int depth
= 0 ) const;
1354 void SetError( int err
, const char* errorLocation
, TiXmlParsingData
* prevData
, TiXmlEncoding encoding
);
1356 virtual const TiXmlDocument
* ToDocument() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1357 virtual TiXmlDocument
* ToDocument() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1360 virtual void StreamOut ( TIXML_OSTREAM
* out
) const;
1362 virtual TiXmlNode
* Clone() const;
1363 #ifdef TIXML_USE_STL
1364 virtual void StreamIn( TIXML_ISTREAM
* in
, TIXML_STRING
* tag
);
1368 void CopyTo( TiXmlDocument
* target
) const;
1372 TIXML_STRING errorDesc
;
1374 TiXmlCursor errorLocation
;
1375 bool useMicrosoftBOM
; // the UTF-8 BOM were found when read. Note this, and try to write.
1380 A TiXmlHandle is a class that wraps a node pointer with null checks; this is
1381 an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml
1382 DOM structure. It is a separate utility class.
1387 <Element attributeA = "valueA">
1388 <Child attributeB = "value1" />
1389 <Child attributeB = "value2" />
1394 Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very
1395 easy to write a *lot* of code that looks like:
1398 TiXmlElement* root = document.FirstChildElement( "Document" );
1401 TiXmlElement* element = root->FirstChildElement( "Element" );
1404 TiXmlElement* child = element->FirstChildElement( "Child" );
1407 TiXmlElement* child2 = child->NextSiblingElement( "Child" );
1410 // Finally do something useful.
1413 And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity
1414 of such code. A TiXmlHandle checks for null pointers so it is perfectly safe
1418 TiXmlHandle docHandle( &document );
1419 TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).Element();
1422 // do something useful
1425 Which is MUCH more concise and useful.
1427 It is also safe to copy handles - internally they are nothing more than node pointers.
1429 TiXmlHandle handleCopy = handle;
1432 What they should not be used for is iteration:
1438 TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).Element();
1446 It seems reasonable, but it is in fact two embedded while loops. The Child method is
1447 a linear walk to find the element, so this code would iterate much more than it needs
1448 to. Instead, prefer:
1451 TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).Element();
1453 for( child; child; child=child->NextSiblingElement() )
1462 /// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
1463 TiXmlHandle( TiXmlNode
* _node
) { this->node
= _node
; }
1464 /// Copy constructor
1465 TiXmlHandle( const TiXmlHandle
& ref
) { this->node
= ref
.node
; }
1466 TiXmlHandle
operator=( const TiXmlHandle
& ref
) { this->node
= ref
.node
; return *this; }
1468 /// Return a handle to the first child node.
1469 TiXmlHandle
FirstChild() const;
1470 /// Return a handle to the first child node with the given name.
1471 TiXmlHandle
FirstChild( const char * value
) const;
1472 /// Return a handle to the first child element.
1473 TiXmlHandle
FirstChildElement() const;
1474 /// Return a handle to the first child element with the given name.
1475 TiXmlHandle
FirstChildElement( const char * value
) const;
1477 /** Return a handle to the "index" child with the given name.
1478 The first child is 0, the second 1, etc.
1480 TiXmlHandle
Child( const char* value
, int index
) const;
1481 /** Return a handle to the "index" child.
1482 The first child is 0, the second 1, etc.
1484 TiXmlHandle
Child( int index
) const;
1485 /** Return a handle to the "index" child element with the given name.
1486 The first child element is 0, the second 1, etc. Note that only TiXmlElements
1487 are indexed: other types are not counted.
1489 TiXmlHandle
ChildElement( const char* value
, int index
) const;
1490 /** Return a handle to the "index" child element.
1491 The first child element is 0, the second 1, etc. Note that only TiXmlElements
1492 are indexed: other types are not counted.
1494 TiXmlHandle
ChildElement( int index
) const;
1496 #ifdef TIXML_USE_STL
1497 TiXmlHandle
FirstChild( const std::string
& _value
) const { return FirstChild( _value
.c_str() ); }
1498 TiXmlHandle
FirstChildElement( const std::string
& _value
) const { return FirstChildElement( _value
.c_str() ); }
1500 TiXmlHandle
Child( const std::string
& _value
, int index
) const { return Child( _value
.c_str(), index
); }
1501 TiXmlHandle
ChildElement( const std::string
& _value
, int index
) const { return ChildElement( _value
.c_str(), index
); }
1504 /// Return the handle as a TiXmlNode. This may return null.
1505 TiXmlNode
* Node() const { return node
; }
1506 /// Return the handle as a TiXmlElement. This may return null.
1507 TiXmlElement
* Element() const { return ( ( node
&& node
->ToElement() ) ? node
->ToElement() : 0 ); }
1508 /// Return the handle as a TiXmlText. This may return null.
1509 TiXmlText
* Text() const { return ( ( node
&& node
->ToText() ) ? node
->ToText() : 0 ); }
1510 /// Return the handle as a TiXmlUnknown. This may return null;
1511 TiXmlUnknown
* Unknown() const { return ( ( node
&& node
->ToUnknown() ) ? node
->ToUnknown() : 0 ); }
1518 #pragma warning( pop )