2 Original code by Lee Thomason (www.grinninglizard.com)
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any
6 damages arising from the use of this software.
8 Permission is granted to anyone to use this software for any
9 purpose, including commercial applications, and to alter it and
10 redistribute it freely, subject to the following restrictions:
12 1. The origin of this software must not be misrepresented; you must
13 not claim that you wrote the original software. If you use this
14 software in a product, an acknowledgment in the product documentation
15 would be appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and
18 must not be misrepresented as being the original software.
20 3. This notice may not be removed or altered from any source
24 #ifndef TINYXML2_INCLUDED
25 #define TINYXML2_INCLUDED
27 #if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__)
44 TODO: intern strings instead of allocation.
48 g++ -Wall -DDEBUG tinyxml2.cpp xmltest.cpp -o gccxmltest.exe
50 Formatting, Artistic Style:
51 AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h
54 #if defined( _DEBUG ) || defined( DEBUG ) || defined (__DEBUG__)
61 # pragma warning(push)
62 # pragma warning(disable: 4251)
66 # ifdef TINYXML2_EXPORT
67 # define TINYXML2_LIB __declspec(dllexport)
68 # elif defined(TINYXML2_IMPORT)
69 # define TINYXML2_LIB __declspec(dllimport)
79 # if defined(_MSC_VER)
80 # // "(void)0," is for suppressing C4127 warning in "assert(false)", "assert(true)" and the like
81 # define TIXMLASSERT( x ) if ( !((void)0,(x))) { __debugbreak(); } //if ( !(x)) WinDebugBreak()
82 # elif defined (ANDROID_NDK)
83 # include <android/log.h>
84 # define TIXMLASSERT( x ) if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); }
87 # define TIXMLASSERT assert
90 # define TIXMLASSERT( x ) {}
94 #if defined(_MSC_VER) && (_MSC_VER >= 1400 ) && (!defined WINCE)
95 // Microsoft visual studio, version 2005 and higher.
100 const char *format [,
103 inline int TIXML_SNPRINTF( char* buffer
, size_t size
, const char* format
, ... )
106 va_start( va
, format
);
107 int result
= vsnprintf_s( buffer
, size
, _TRUNCATE
, format
, va
);
111 #define TIXML_SSCANF sscanf_s
113 #define TIXML_SNPRINTF _snprintf
114 #define TIXML_SSCANF sscanf
116 // GCC version 3 and higher
117 //#warning( "Using sn* functions." )
118 #define TIXML_SNPRINTF snprintf
119 #define TIXML_SSCANF sscanf
122 /* Versioning, past 1.0.14:
125 static const int TIXML2_MAJOR_VERSION
= 3;
126 static const int TIXML2_MINOR_VERSION
= 0;
127 static const int TIXML2_PATCH_VERSION
= 0;
136 class XMLDeclaration
;
141 A class that wraps strings. Normally stores the start and end
142 pointers into the XML file itself, and will apply normalization
143 and entity translation if actually read. Can also store (and memory
144 manage) a traditional char[]
150 NEEDS_ENTITY_PROCESSING
= 0x01,
151 NEEDS_NEWLINE_NORMALIZATION
= 0x02,
152 COLLAPSE_WHITESPACE
= 0x04,
154 TEXT_ELEMENT
= NEEDS_ENTITY_PROCESSING
| NEEDS_NEWLINE_NORMALIZATION
,
155 TEXT_ELEMENT_LEAVE_ENTITIES
= NEEDS_NEWLINE_NORMALIZATION
,
157 ATTRIBUTE_VALUE
= NEEDS_ENTITY_PROCESSING
| NEEDS_NEWLINE_NORMALIZATION
,
158 ATTRIBUTE_VALUE_LEAVE_ENTITIES
= NEEDS_NEWLINE_NORMALIZATION
,
159 COMMENT
= NEEDS_NEWLINE_NORMALIZATION
162 StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {}
165 void Set( char* start
, char* end
, int flags
) {
169 _flags
= flags
| NEEDS_FLUSH
;
172 const char* GetStr();
175 return _start
== _end
;
178 void SetInternedStr( const char* str
) {
180 _start
= const_cast<char*>(str
);
183 void SetStr( const char* str
, int flags
=0 );
185 char* ParseText( char* in
, const char* endTag
, int strFlags
);
186 char* ParseName( char* in
);
188 void TransferTo( StrPair
* other
);
192 void CollapseWhitespace();
199 // After parsing, if *_end != 0, it can be set to zero.
204 StrPair( const StrPair
& other
); // not supported
205 void operator=( StrPair
& other
); // not supported, use TransferTo()
210 A dynamic array of Plain Old Data. Doesn't support constructors, etc.
211 Has a small initial memory pool, so that low or no usage will not
212 cause a call to new/delete
214 template <class T
, int INIT
>
225 if ( _mem
!= _pool
) {
235 TIXMLASSERT( _size
< INT_MAX
);
236 EnsureCapacity( _size
+1 );
240 T
* PushArr( int count
) {
241 TIXMLASSERT( count
>= 0 );
242 TIXMLASSERT( _size
<= INT_MAX
- count
);
243 EnsureCapacity( _size
+count
);
244 T
* ret
= &_mem
[_size
];
250 TIXMLASSERT( _size
> 0 );
251 return _mem
[--_size
];
254 void PopArr( int count
) {
255 TIXMLASSERT( _size
>= count
);
263 T
& operator[](int i
) {
264 TIXMLASSERT( i
>= 0 && i
< _size
);
268 const T
& operator[](int i
) const {
269 TIXMLASSERT( i
>= 0 && i
< _size
);
273 const T
& PeekTop() const {
274 TIXMLASSERT( _size
> 0 );
275 return _mem
[ _size
- 1];
279 TIXMLASSERT( _size
>= 0 );
283 int Capacity() const {
287 const T
* Mem() const {
296 DynArray( const DynArray
& ); // not supported
297 void operator=( const DynArray
& ); // not supported
299 void EnsureCapacity( int cap
) {
300 TIXMLASSERT( cap
> 0 );
301 if ( cap
> _allocated
) {
302 TIXMLASSERT( cap
<= INT_MAX
/ 2 );
303 int newAllocated
= cap
* 2;
304 T
* newMem
= new T
[newAllocated
];
305 memcpy( newMem
, _mem
, sizeof(T
)*_size
); // warning: not using constructors, only works for PODs
306 if ( _mem
!= _pool
) {
310 _allocated
= newAllocated
;
316 int _allocated
; // objects allocated
317 int _size
; // number objects in use
322 Parent virtual class of a pool for fast allocation
323 and deallocation of objects.
329 virtual ~MemPool() {}
331 virtual int ItemSize() const = 0;
332 virtual void* Alloc() = 0;
333 virtual void Free( void* ) = 0;
334 virtual void SetTracked() = 0;
335 virtual void Clear() = 0;
340 Template child class to create pools of the correct type.
343 class MemPoolT
: public MemPool
346 MemPoolT() : _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {}
352 // Delete the blocks.
353 while( !_blockPtrs
.Empty()) {
354 Block
* b
= _blockPtrs
.Pop();
364 virtual int ItemSize() const {
367 int CurrentAllocs() const {
368 return _currentAllocs
;
371 virtual void* Alloc() {
374 Block
* block
= new Block();
375 _blockPtrs
.Push( block
);
377 for( int i
=0; i
<COUNT
-1; ++i
) {
378 block
->chunk
[i
].next
= &block
->chunk
[i
+1];
380 block
->chunk
[COUNT
-1].next
= 0;
381 _root
= block
->chunk
;
383 void* result
= _root
;
387 if ( _currentAllocs
> _maxAllocs
) {
388 _maxAllocs
= _currentAllocs
;
395 virtual void Free( void* mem
) {
400 Chunk
* chunk
= static_cast<Chunk
*>( mem
);
402 memset( chunk
, 0xfe, sizeof(Chunk
) );
407 void Trace( const char* name
) {
408 printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n",
409 name
, _maxAllocs
, _maxAllocs
*SIZE
/1024, _currentAllocs
, SIZE
, _nAllocs
, _blockPtrs
.Size() );
416 int Untracked() const {
420 // This number is perf sensitive. 4k seems like a good tradeoff on my machine.
421 // The test file is large, 170k.
422 // Release: VS2010 gcc(no opt)
429 enum { COUNT
= (4*1024)/SIZE
}; // Some compilers do not accept to use COUNT in private part if COUNT is private
432 MemPoolT( const MemPoolT
& ); // not supported
433 void operator=( const MemPoolT
& ); // not supported
442 DynArray
< Block
*, 10 > _blockPtrs
;
454 Implements the interface to the "Visitor pattern" (see the Accept() method.)
455 If you call the Accept() method, it requires being passed a XMLVisitor
456 class to handle callbacks. For nodes that contain other nodes (Document, Element)
457 you will get called with a VisitEnter/VisitExit pair. Nodes that are always leafs
458 are simply called with Visit().
460 If you return 'true' from a Visit method, recursive parsing will continue. If you return
461 false, <b>no children of this node or its siblings</b> will be visited.
463 All flavors of Visit methods have a default implementation that returns 'true' (continue
464 visiting). You need to only override methods that are interesting to you.
466 Generally Accept() is called on the XMLDocument, although all nodes support visiting.
468 You should never change the document from a callback.
470 @sa XMLNode::Accept()
472 class TINYXML2_LIB XMLVisitor
475 virtual ~XMLVisitor() {}
477 /// Visit a document.
478 virtual bool VisitEnter( const XMLDocument
& /*doc*/ ) {
481 /// Visit a document.
482 virtual bool VisitExit( const XMLDocument
& /*doc*/ ) {
486 /// Visit an element.
487 virtual bool VisitEnter( const XMLElement
& /*element*/, const XMLAttribute
* /*firstAttribute*/ ) {
490 /// Visit an element.
491 virtual bool VisitExit( const XMLElement
& /*element*/ ) {
495 /// Visit a declaration.
496 virtual bool Visit( const XMLDeclaration
& /*declaration*/ ) {
499 /// Visit a text node.
500 virtual bool Visit( const XMLText
& /*text*/ ) {
503 /// Visit a comment node.
504 virtual bool Visit( const XMLComment
& /*comment*/ ) {
507 /// Visit an unknown node.
508 virtual bool Visit( const XMLUnknown
& /*unknown*/ ) {
513 // WARNING: must match XMLDocument::_errorNames[]
518 XML_WRONG_ATTRIBUTE_TYPE
,
519 XML_ERROR_FILE_NOT_FOUND
,
520 XML_ERROR_FILE_COULD_NOT_BE_OPENED
,
521 XML_ERROR_FILE_READ_ERROR
,
522 XML_ERROR_ELEMENT_MISMATCH
,
523 XML_ERROR_PARSING_ELEMENT
,
524 XML_ERROR_PARSING_ATTRIBUTE
,
525 XML_ERROR_IDENTIFYING_TAG
,
526 XML_ERROR_PARSING_TEXT
,
527 XML_ERROR_PARSING_CDATA
,
528 XML_ERROR_PARSING_COMMENT
,
529 XML_ERROR_PARSING_DECLARATION
,
530 XML_ERROR_PARSING_UNKNOWN
,
531 XML_ERROR_EMPTY_DOCUMENT
,
532 XML_ERROR_MISMATCHED_ELEMENT
,
534 XML_CAN_NOT_CONVERT_TEXT
,
542 Utility functionality.
547 static const char* SkipWhiteSpace( const char* p
) {
549 while( IsWhiteSpace(*p
) ) {
555 static char* SkipWhiteSpace( char* p
) {
556 return const_cast<char*>( SkipWhiteSpace( const_cast<const char*>(p
) ) );
559 // Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't
560 // correct, but simple, and usually works.
561 static bool IsWhiteSpace( char p
) {
562 return !IsUTF8Continuation(p
) && isspace( static_cast<unsigned char>(p
) );
565 inline static bool IsNameStartChar( unsigned char ch
) {
567 // This is a heuristic guess in attempt to not implement Unicode-aware isalpha()
570 if ( isalpha( ch
) ) {
573 return ch
== ':' || ch
== '_';
576 inline static bool IsNameChar( unsigned char ch
) {
577 return IsNameStartChar( ch
)
583 inline static bool StringEqual( const char* p
, const char* q
, int nChar
=INT_MAX
) {
588 while( *p
&& *q
&& *p
== *q
&& n
<nChar
) {
593 if ( (n
== nChar
) || ( *p
== 0 && *q
== 0 ) ) {
599 inline static bool IsUTF8Continuation( const char p
) {
600 return ( p
& 0x80 ) != 0;
603 static const char* ReadBOM( const char* p
, bool* hasBOM
);
604 // p is the starting location,
605 // the UTF-8 value of the entity will be placed in value, and length filled in.
606 static const char* GetCharacterRef( const char* p
, char* value
, int* length
);
607 static void ConvertUTF32ToUTF8( unsigned long input
, char* output
, int* length
);
609 // converts primitive types to strings
610 static void ToStr( int v
, char* buffer
, int bufferSize
);
611 static void ToStr( unsigned v
, char* buffer
, int bufferSize
);
612 static void ToStr( bool v
, char* buffer
, int bufferSize
);
613 static void ToStr( float v
, char* buffer
, int bufferSize
);
614 static void ToStr( double v
, char* buffer
, int bufferSize
);
616 // converts strings to primitive types
617 static bool ToInt( const char* str
, int* value
);
618 static bool ToUnsigned( const char* str
, unsigned* value
);
619 static bool ToBool( const char* str
, bool* value
);
620 static bool ToFloat( const char* str
, float* value
);
621 static bool ToDouble( const char* str
, double* value
);
625 /** XMLNode is a base class for every object that is in the
626 XML Document Object Model (DOM), except XMLAttributes.
627 Nodes have siblings, a parent, and children which can
628 be navigated. A node is always in a XMLDocument.
629 The type of a XMLNode can be queried, and it can
630 be cast to its more defined type.
632 A XMLDocument allocates memory for all its Nodes.
633 When the XMLDocument gets deleted, all its Nodes
634 will also be deleted.
637 A Document can contain: Element (container or leaf)
642 An Element can contain: Element (container or leaf)
644 Attributes (not on tree)
650 class TINYXML2_LIB XMLNode
652 friend class XMLDocument
;
653 friend class XMLElement
;
656 /// Get the XMLDocument that owns this XMLNode.
657 const XMLDocument
* GetDocument() const {
660 /// Get the XMLDocument that owns this XMLNode.
661 XMLDocument
* GetDocument() {
665 /// Safely cast to an Element, or null.
666 virtual XMLElement
* ToElement() {
669 /// Safely cast to Text, or null.
670 virtual XMLText
* ToText() {
673 /// Safely cast to a Comment, or null.
674 virtual XMLComment
* ToComment() {
677 /// Safely cast to a Document, or null.
678 virtual XMLDocument
* ToDocument() {
681 /// Safely cast to a Declaration, or null.
682 virtual XMLDeclaration
* ToDeclaration() {
685 /// Safely cast to an Unknown, or null.
686 virtual XMLUnknown
* ToUnknown() {
690 virtual const XMLElement
* ToElement() const {
693 virtual const XMLText
* ToText() const {
696 virtual const XMLComment
* ToComment() const {
699 virtual const XMLDocument
* ToDocument() const {
702 virtual const XMLDeclaration
* ToDeclaration() const {
705 virtual const XMLUnknown
* ToUnknown() const {
709 /** The meaning of 'value' changes for the specific type.
712 Element: name of the element
713 Comment: the comment text
714 Unknown: the tag contents
715 Text: the text string
718 const char* Value() const;
720 /** Set the Value of an XML node.
723 void SetValue( const char* val
, bool staticMem
=false );
725 /// Get the parent of this node on the DOM.
726 const XMLNode
* Parent() const {
734 /// Returns true if this node has no children.
735 bool NoChildren() const {
739 /// Get the first child node, or null if none exists.
740 const XMLNode
* FirstChild() const {
744 XMLNode
* FirstChild() {
748 /** Get the first child element, or optionally the first child
749 element with the specified name.
751 const XMLElement
* FirstChildElement( const char* value
=0 ) const;
753 XMLElement
* FirstChildElement( const char* value
=0 ) {
754 return const_cast<XMLElement
*>(const_cast<const XMLNode
*>(this)->FirstChildElement( value
));
757 /// Get the last child node, or null if none exists.
758 const XMLNode
* LastChild() const {
762 XMLNode
* LastChild() {
763 return const_cast<XMLNode
*>(const_cast<const XMLNode
*>(this)->LastChild() );
766 /** Get the last child element or optionally the last child
767 element with the specified name.
769 const XMLElement
* LastChildElement( const char* value
=0 ) const;
771 XMLElement
* LastChildElement( const char* value
=0 ) {
772 return const_cast<XMLElement
*>(const_cast<const XMLNode
*>(this)->LastChildElement(value
) );
775 /// Get the previous (left) sibling node of this node.
776 const XMLNode
* PreviousSibling() const {
780 XMLNode
* PreviousSibling() {
784 /// Get the previous (left) sibling element of this node, with an optionally supplied name.
785 const XMLElement
* PreviousSiblingElement( const char* value
=0 ) const ;
787 XMLElement
* PreviousSiblingElement( const char* value
=0 ) {
788 return const_cast<XMLElement
*>(const_cast<const XMLNode
*>(this)->PreviousSiblingElement( value
) );
791 /// Get the next (right) sibling node of this node.
792 const XMLNode
* NextSibling() const {
796 XMLNode
* NextSibling() {
800 /// Get the next (right) sibling element of this node, with an optionally supplied name.
801 const XMLElement
* NextSiblingElement( const char* value
=0 ) const;
803 XMLElement
* NextSiblingElement( const char* value
=0 ) {
804 return const_cast<XMLElement
*>(const_cast<const XMLNode
*>(this)->NextSiblingElement( value
) );
808 Add a child node as the last (right) child.
809 If the child node is already part of the document,
810 it is moved from its old location to the new location.
811 Returns the addThis argument or 0 if the node does not
812 belong to the same document.
814 XMLNode
* InsertEndChild( XMLNode
* addThis
);
816 XMLNode
* LinkEndChild( XMLNode
* addThis
) {
817 return InsertEndChild( addThis
);
820 Add a child node as the first (left) child.
821 If the child node is already part of the document,
822 it is moved from its old location to the new location.
823 Returns the addThis argument or 0 if the node does not
824 belong to the same document.
826 XMLNode
* InsertFirstChild( XMLNode
* addThis
);
828 Add a node after the specified child node.
829 If the child node is already part of the document,
830 it is moved from its old location to the new location.
831 Returns the addThis argument or 0 if the afterThis node
832 is not a child of this node, or if the node does not
833 belong to the same document.
835 XMLNode
* InsertAfterChild( XMLNode
* afterThis
, XMLNode
* addThis
);
838 Delete all the children of this node.
840 void DeleteChildren();
843 Delete a child of this node.
845 void DeleteChild( XMLNode
* node
);
848 Make a copy of this node, but not its children.
849 You may pass in a Document pointer that will be
850 the owner of the new Node. If the 'document' is
851 null, then the node returned will be allocated
852 from the current Document. (this->GetDocument())
854 Note: if called on a XMLDocument, this will return null.
856 virtual XMLNode
* ShallowClone( XMLDocument
* document
) const = 0;
859 Test if 2 nodes are the same, but don't test children.
860 The 2 nodes do not need to be in the same Document.
862 Note: if called on a XMLDocument, this will return false.
864 virtual bool ShallowEqual( const XMLNode
* compare
) const = 0;
866 /** Accept a hierarchical visit of the nodes in the TinyXML-2 DOM. Every node in the
867 XML tree will be conditionally visited and the host will be called back
868 via the XMLVisitor interface.
870 This is essentially a SAX interface for TinyXML-2. (Note however it doesn't re-parse
871 the XML for the callbacks, so the performance of TinyXML-2 is unchanged by using this
872 interface versus any other.)
874 The interface has been based on ideas from:
876 - http://www.saxproject.org/
877 - http://c2.com/cgi/wiki?HierarchicalVisitorPattern
879 Which are both good references for "visiting".
881 An example of using Accept():
884 tinyxmlDoc.Accept( &printer );
885 const char* xmlcstr = printer.CStr();
888 virtual bool Accept( XMLVisitor
* visitor
) const = 0;
891 virtual char* ParseDeep( char*, StrPair
* );
894 XMLNode( XMLDocument
* );
897 XMLDocument
* _document
;
899 mutable StrPair _value
;
901 XMLNode
* _firstChild
;
909 void Unlink( XMLNode
* child
);
910 static void DeleteNode( XMLNode
* node
);
911 void InsertChildPreamble( XMLNode
* insertThis
) const;
913 XMLNode( const XMLNode
& ); // not supported
914 XMLNode
& operator=( const XMLNode
& ); // not supported
920 Note that a text node can have child element nodes, for example:
922 <root>This is <b>bold</b></root>
925 A text node can have 2 ways to output the next. "normal" output
926 and CDATA. It will default to the mode it was parsed from the XML file and
927 you generally want to leave it alone, but you can change the output mode with
928 SetCData() and query it with CData().
930 class TINYXML2_LIB XMLText
: public XMLNode
932 friend class XMLBase
;
933 friend class XMLDocument
;
935 virtual bool Accept( XMLVisitor
* visitor
) const;
937 virtual XMLText
* ToText() {
940 virtual const XMLText
* ToText() const {
944 /// Declare whether this should be CDATA or standard text.
945 void SetCData( bool isCData
) {
948 /// Returns true if this is a CDATA text element.
953 char* ParseDeep( char*, StrPair
* endTag
);
954 virtual XMLNode
* ShallowClone( XMLDocument
* document
) const;
955 virtual bool ShallowEqual( const XMLNode
* compare
) const;
958 XMLText( XMLDocument
* doc
) : XMLNode( doc
), _isCData( false ) {}
959 virtual ~XMLText() {}
964 XMLText( const XMLText
& ); // not supported
965 XMLText
& operator=( const XMLText
& ); // not supported
969 /** An XML Comment. */
970 class TINYXML2_LIB XMLComment
: public XMLNode
972 friend class XMLDocument
;
974 virtual XMLComment
* ToComment() {
977 virtual const XMLComment
* ToComment() const {
981 virtual bool Accept( XMLVisitor
* visitor
) const;
983 char* ParseDeep( char*, StrPair
* endTag
);
984 virtual XMLNode
* ShallowClone( XMLDocument
* document
) const;
985 virtual bool ShallowEqual( const XMLNode
* compare
) const;
988 XMLComment( XMLDocument
* doc
);
989 virtual ~XMLComment();
992 XMLComment( const XMLComment
& ); // not supported
993 XMLComment
& operator=( const XMLComment
& ); // not supported
997 /** In correct XML the declaration is the first entry in the file.
999 <?xml version="1.0" standalone="yes"?>
1002 TinyXML-2 will happily read or write files without a declaration,
1005 The text of the declaration isn't interpreted. It is parsed
1006 and written as a string.
1008 class TINYXML2_LIB XMLDeclaration
: public XMLNode
1010 friend class XMLDocument
;
1012 virtual XMLDeclaration
* ToDeclaration() {
1015 virtual const XMLDeclaration
* ToDeclaration() const {
1019 virtual bool Accept( XMLVisitor
* visitor
) const;
1021 char* ParseDeep( char*, StrPair
* endTag
);
1022 virtual XMLNode
* ShallowClone( XMLDocument
* document
) const;
1023 virtual bool ShallowEqual( const XMLNode
* compare
) const;
1026 XMLDeclaration( XMLDocument
* doc
);
1027 virtual ~XMLDeclaration();
1030 XMLDeclaration( const XMLDeclaration
& ); // not supported
1031 XMLDeclaration
& operator=( const XMLDeclaration
& ); // not supported
1035 /** Any tag that TinyXML-2 doesn't recognize is saved as an
1036 unknown. It is a tag of text, but should not be modified.
1037 It will be written back to the XML, unchanged, when the file
1040 DTD tags get thrown into XMLUnknowns.
1042 class TINYXML2_LIB XMLUnknown
: public XMLNode
1044 friend class XMLDocument
;
1046 virtual XMLUnknown
* ToUnknown() {
1049 virtual const XMLUnknown
* ToUnknown() const {
1053 virtual bool Accept( XMLVisitor
* visitor
) const;
1055 char* ParseDeep( char*, StrPair
* endTag
);
1056 virtual XMLNode
* ShallowClone( XMLDocument
* document
) const;
1057 virtual bool ShallowEqual( const XMLNode
* compare
) const;
1060 XMLUnknown( XMLDocument
* doc
);
1061 virtual ~XMLUnknown();
1064 XMLUnknown( const XMLUnknown
& ); // not supported
1065 XMLUnknown
& operator=( const XMLUnknown
& ); // not supported
1070 /** An attribute is a name-value pair. Elements have an arbitrary
1071 number of attributes, each with a unique name.
1073 @note The attributes are not XMLNodes. You may only query the
1074 Next() attribute in a list.
1076 class TINYXML2_LIB XMLAttribute
1078 friend class XMLElement
;
1080 /// The name of the attribute.
1081 const char* Name() const;
1083 /// The value of the attribute.
1084 const char* Value() const;
1086 /// The next attribute in the list.
1087 const XMLAttribute
* Next() const {
1091 /** IntValue interprets the attribute as an integer, and returns the value.
1092 If the value isn't an integer, 0 will be returned. There is no error checking;
1093 use QueryIntValue() if you need error checking.
1095 int IntValue() const {
1097 QueryIntValue( &i
);
1100 /// Query as an unsigned integer. See IntValue()
1101 unsigned UnsignedValue() const {
1103 QueryUnsignedValue( &i
);
1106 /// Query as a boolean. See IntValue()
1107 bool BoolValue() const {
1109 QueryBoolValue( &b
);
1112 /// Query as a double. See IntValue()
1113 double DoubleValue() const {
1115 QueryDoubleValue( &d
);
1118 /// Query as a float. See IntValue()
1119 float FloatValue() const {
1121 QueryFloatValue( &f
);
1125 /** QueryIntValue interprets the attribute as an integer, and returns the value
1126 in the provided parameter. The function will return XML_NO_ERROR on success,
1127 and XML_WRONG_ATTRIBUTE_TYPE if the conversion is not successful.
1129 XMLError
QueryIntValue( int* value
) const;
1130 /// See QueryIntValue
1131 XMLError
QueryUnsignedValue( unsigned int* value
) const;
1132 /// See QueryIntValue
1133 XMLError
QueryBoolValue( bool* value
) const;
1134 /// See QueryIntValue
1135 XMLError
QueryDoubleValue( double* value
) const;
1136 /// See QueryIntValue
1137 XMLError
QueryFloatValue( float* value
) const;
1139 /// Set the attribute to a string value.
1140 void SetAttribute( const char* value
);
1141 /// Set the attribute to value.
1142 void SetAttribute( int value
);
1143 /// Set the attribute to value.
1144 void SetAttribute( unsigned value
);
1145 /// Set the attribute to value.
1146 void SetAttribute( bool value
);
1147 /// Set the attribute to value.
1148 void SetAttribute( double value
);
1149 /// Set the attribute to value.
1150 void SetAttribute( float value
);
1153 enum { BUF_SIZE
= 200 };
1155 XMLAttribute() : _next( 0 ), _memPool( 0 ) {}
1156 virtual ~XMLAttribute() {}
1158 XMLAttribute( const XMLAttribute
& ); // not supported
1159 void operator=( const XMLAttribute
& ); // not supported
1160 void SetName( const char* name
);
1162 char* ParseDeep( char* p
, bool processEntities
);
1164 mutable StrPair _name
;
1165 mutable StrPair _value
;
1166 XMLAttribute
* _next
;
1171 /** The element is a container class. It has a value, the element name,
1172 and can contain other elements, text, comments, and unknowns.
1173 Elements also contain an arbitrary number of attributes.
1175 class TINYXML2_LIB XMLElement
: public XMLNode
1177 friend class XMLBase
;
1178 friend class XMLDocument
;
1180 /// Get the name of an element (which is the Value() of the node.)
1181 const char* Name() const {
1184 /// Set the name of the element.
1185 void SetName( const char* str
, bool staticMem
=false ) {
1186 SetValue( str
, staticMem
);
1189 virtual XMLElement
* ToElement() {
1192 virtual const XMLElement
* ToElement() const {
1195 virtual bool Accept( XMLVisitor
* visitor
) const;
1197 /** Given an attribute name, Attribute() returns the value
1198 for the attribute of that name, or null if none
1199 exists. For example:
1202 const char* value = ele->Attribute( "foo" );
1205 The 'value' parameter is normally null. However, if specified,
1206 the attribute will only be returned if the 'name' and 'value'
1207 match. This allow you to write code:
1210 if ( ele->Attribute( "foo", "bar" ) ) callFooIsBar();
1215 if ( ele->Attribute( "foo" ) ) {
1216 if ( strcmp( ele->Attribute( "foo" ), "bar" ) == 0 ) callFooIsBar();
1220 const char* Attribute( const char* name
, const char* value
=0 ) const;
1222 /** Given an attribute name, IntAttribute() returns the value
1223 of the attribute interpreted as an integer. 0 will be
1224 returned if there is an error. For a method with error
1225 checking, see QueryIntAttribute()
1227 int IntAttribute( const char* name
) const {
1229 QueryIntAttribute( name
, &i
);
1232 /// See IntAttribute()
1233 unsigned UnsignedAttribute( const char* name
) const {
1235 QueryUnsignedAttribute( name
, &i
);
1238 /// See IntAttribute()
1239 bool BoolAttribute( const char* name
) const {
1241 QueryBoolAttribute( name
, &b
);
1244 /// See IntAttribute()
1245 double DoubleAttribute( const char* name
) const {
1247 QueryDoubleAttribute( name
, &d
);
1250 /// See IntAttribute()
1251 float FloatAttribute( const char* name
) const {
1253 QueryFloatAttribute( name
, &f
);
1257 /** Given an attribute name, QueryIntAttribute() returns
1258 XML_NO_ERROR, XML_WRONG_ATTRIBUTE_TYPE if the conversion
1259 can't be performed, or XML_NO_ATTRIBUTE if the attribute
1260 doesn't exist. If successful, the result of the conversion
1261 will be written to 'value'. If not successful, nothing will
1262 be written to 'value'. This allows you to provide default
1267 QueryIntAttribute( "foo", &value ); // if "foo" isn't found, value will still be 10
1270 XMLError
QueryIntAttribute( const char* name
, int* value
) const {
1271 const XMLAttribute
* a
= FindAttribute( name
);
1273 return XML_NO_ATTRIBUTE
;
1275 return a
->QueryIntValue( value
);
1277 /// See QueryIntAttribute()
1278 XMLError
QueryUnsignedAttribute( const char* name
, unsigned int* value
) const {
1279 const XMLAttribute
* a
= FindAttribute( name
);
1281 return XML_NO_ATTRIBUTE
;
1283 return a
->QueryUnsignedValue( value
);
1285 /// See QueryIntAttribute()
1286 XMLError
QueryBoolAttribute( const char* name
, bool* value
) const {
1287 const XMLAttribute
* a
= FindAttribute( name
);
1289 return XML_NO_ATTRIBUTE
;
1291 return a
->QueryBoolValue( value
);
1293 /// See QueryIntAttribute()
1294 XMLError
QueryDoubleAttribute( const char* name
, double* value
) const {
1295 const XMLAttribute
* a
= FindAttribute( name
);
1297 return XML_NO_ATTRIBUTE
;
1299 return a
->QueryDoubleValue( value
);
1301 /// See QueryIntAttribute()
1302 XMLError
QueryFloatAttribute( const char* name
, float* value
) const {
1303 const XMLAttribute
* a
= FindAttribute( name
);
1305 return XML_NO_ATTRIBUTE
;
1307 return a
->QueryFloatValue( value
);
1311 /** Given an attribute name, QueryAttribute() returns
1312 XML_NO_ERROR, XML_WRONG_ATTRIBUTE_TYPE if the conversion
1313 can't be performed, or XML_NO_ATTRIBUTE if the attribute
1314 doesn't exist. It is overloaded for the primitive types,
1315 and is a generally more convenient replacement of
1316 QueryIntAttribute() and related functions.
1318 If successful, the result of the conversion
1319 will be written to 'value'. If not successful, nothing will
1320 be written to 'value'. This allows you to provide default
1325 QueryAttribute( "foo", &value ); // if "foo" isn't found, value will still be 10
1328 int QueryAttribute( const char* name
, int* value
) const {
1329 return QueryIntAttribute( name
, value
);
1332 int QueryAttribute( const char* name
, unsigned int* value
) const {
1333 return QueryUnsignedAttribute( name
, value
);
1336 int QueryAttribute( const char* name
, bool* value
) const {
1337 return QueryBoolAttribute( name
, value
);
1340 int QueryAttribute( const char* name
, double* value
) const {
1341 return QueryDoubleAttribute( name
, value
);
1344 int QueryAttribute( const char* name
, float* value
) const {
1345 return QueryFloatAttribute( name
, value
);
1348 /// Sets the named attribute to value.
1349 void SetAttribute( const char* name
, const char* value
) {
1350 XMLAttribute
* a
= FindOrCreateAttribute( name
);
1351 a
->SetAttribute( value
);
1353 /// Sets the named attribute to value.
1354 void SetAttribute( const char* name
, int value
) {
1355 XMLAttribute
* a
= FindOrCreateAttribute( name
);
1356 a
->SetAttribute( value
);
1358 /// Sets the named attribute to value.
1359 void SetAttribute( const char* name
, unsigned value
) {
1360 XMLAttribute
* a
= FindOrCreateAttribute( name
);
1361 a
->SetAttribute( value
);
1363 /// Sets the named attribute to value.
1364 void SetAttribute( const char* name
, bool value
) {
1365 XMLAttribute
* a
= FindOrCreateAttribute( name
);
1366 a
->SetAttribute( value
);
1368 /// Sets the named attribute to value.
1369 void SetAttribute( const char* name
, double value
) {
1370 XMLAttribute
* a
= FindOrCreateAttribute( name
);
1371 a
->SetAttribute( value
);
1373 /// Sets the named attribute to value.
1374 void SetAttribute( const char* name
, float value
) {
1375 XMLAttribute
* a
= FindOrCreateAttribute( name
);
1376 a
->SetAttribute( value
);
1380 Delete an attribute.
1382 void DeleteAttribute( const char* name
);
1384 /// Return the first attribute in the list.
1385 const XMLAttribute
* FirstAttribute() const {
1386 return _rootAttribute
;
1388 /// Query a specific attribute in the list.
1389 const XMLAttribute
* FindAttribute( const char* name
) const;
1391 /** Convenience function for easy access to the text inside an element. Although easy
1392 and concise, GetText() is limited compared to getting the XMLText child
1393 and accessing it directly.
1395 If the first child of 'this' is a XMLText, the GetText()
1396 returns the character string of the Text node, else null is returned.
1398 This is a convenient method for getting the text of simple contained text:
1400 <foo>This is text</foo>
1401 const char* str = fooElement->GetText();
1404 'str' will be a pointer to "This is text".
1406 Note that this function can be misleading. If the element foo was created from
1409 <foo><b>This is text</b></foo>
1412 then the value of str would be null. The first child node isn't a text node, it is
1413 another element. From this XML:
1415 <foo>This is <b>text</b></foo>
1417 GetText() will return "This is ".
1419 const char* GetText() const;
1421 /** Convenience function for easy access to the text inside an element. Although easy
1422 and concise, SetText() is limited compared to creating an XMLText child
1423 and mutating it directly.
1425 If the first child of 'this' is a XMLText, SetText() sets its value to
1426 the given string, otherwise it will create a first child that is an XMLText.
1428 This is a convenient method for setting the text of simple contained text:
1430 <foo>This is text</foo>
1431 fooElement->SetText( "Hullaballoo!" );
1432 <foo>Hullaballoo!</foo>
1435 Note that this function can be misleading. If the element foo was created from
1438 <foo><b>This is text</b></foo>
1441 then it will not change "This is text", but rather prefix it with a text element:
1443 <foo>Hullaballoo!<b>This is text</b></foo>
1450 SetText() will generate
1452 <foo>Hullaballoo!</foo>
1455 void SetText( const char* inText
);
1456 /// Convenience method for setting text inside and element. See SetText() for important limitations.
1457 void SetText( int value
);
1458 /// Convenience method for setting text inside and element. See SetText() for important limitations.
1459 void SetText( unsigned value
);
1460 /// Convenience method for setting text inside and element. See SetText() for important limitations.
1461 void SetText( bool value
);
1462 /// Convenience method for setting text inside and element. See SetText() for important limitations.
1463 void SetText( double value
);
1464 /// Convenience method for setting text inside and element. See SetText() for important limitations.
1465 void SetText( float value
);
1468 Convenience method to query the value of a child text node. This is probably best
1469 shown by example. Given you have a document is this form:
1477 The QueryIntText() and similar functions provide a safe and easier way to get to the
1482 float y = 0; // types of x and y are contrived for example
1483 const XMLElement* xElement = pointElement->FirstChildElement( "x" );
1484 const XMLElement* yElement = pointElement->FirstChildElement( "y" );
1485 xElement->QueryIntText( &x );
1486 yElement->QueryFloatText( &y );
1489 @returns XML_SUCCESS (0) on success, XML_CAN_NOT_CONVERT_TEXT if the text cannot be converted
1490 to the requested type, and XML_NO_TEXT_NODE if there is no child text to query.
1493 XMLError
QueryIntText( int* ival
) const;
1494 /// See QueryIntText()
1495 XMLError
QueryUnsignedText( unsigned* uval
) const;
1496 /// See QueryIntText()
1497 XMLError
QueryBoolText( bool* bval
) const;
1498 /// See QueryIntText()
1499 XMLError
QueryDoubleText( double* dval
) const;
1500 /// See QueryIntText()
1501 XMLError
QueryFloatText( float* fval
) const;
1509 int ClosingType() const {
1510 return _closingType
;
1512 char* ParseDeep( char* p
, StrPair
* endTag
);
1513 virtual XMLNode
* ShallowClone( XMLDocument
* document
) const;
1514 virtual bool ShallowEqual( const XMLNode
* compare
) const;
1517 XMLElement( XMLDocument
* doc
);
1518 virtual ~XMLElement();
1519 XMLElement( const XMLElement
& ); // not supported
1520 void operator=( const XMLElement
& ); // not supported
1522 XMLAttribute
* FindAttribute( const char* name
) {
1523 return const_cast<XMLAttribute
*>(const_cast<const XMLElement
*>(this)->FindAttribute( name
));
1525 XMLAttribute
* FindOrCreateAttribute( const char* name
);
1526 //void LinkAttribute( XMLAttribute* attrib );
1527 char* ParseAttributes( char* p
);
1528 static void DeleteAttribute( XMLAttribute
* attribute
);
1530 enum { BUF_SIZE
= 200 };
1532 // The attribute list is ordered; there is no 'lastAttribute'
1533 // because the list needs to be scanned for dupes before adding
1535 XMLAttribute
* _rootAttribute
;
1540 PRESERVE_WHITESPACE
,
1545 /** A Document binds together all the functionality.
1546 It can be saved, loaded, and printed to the screen.
1547 All Nodes are connected and allocated to a Document.
1548 If the Document is deleted, all its Nodes are also deleted.
1550 class TINYXML2_LIB XMLDocument
: public XMLNode
1552 friend class XMLElement
;
1555 XMLDocument( bool processEntities
= true, Whitespace
= PRESERVE_WHITESPACE
);
1558 virtual XMLDocument
* ToDocument() {
1561 virtual const XMLDocument
* ToDocument() const {
1566 Parse an XML file from a character string.
1567 Returns XML_NO_ERROR (0) on success, or
1570 You may optionally pass in the 'nBytes', which is
1571 the number of bytes which will be parsed. If not
1572 specified, TinyXML-2 will assume 'xml' points to a
1573 null terminated string.
1575 XMLError
Parse( const char* xml
, size_t nBytes
=(size_t)(-1) );
1578 Load an XML file from disk.
1579 Returns XML_NO_ERROR (0) on success, or
1582 XMLError
LoadFile( const char* filename
);
1585 Load an XML file from disk. You are responsible
1586 for providing and closing the FILE*.
1588 NOTE: The file should be opened as binary ("rb")
1589 not text in order for TinyXML-2 to correctly
1590 do newline normalization.
1592 Returns XML_NO_ERROR (0) on success, or
1595 XMLError
LoadFile( FILE* );
1598 Save the XML file to disk.
1599 Returns XML_NO_ERROR (0) on success, or
1602 XMLError
SaveFile( const char* filename
, bool compact
= false );
1605 Save the XML file to disk. You are responsible
1606 for providing and closing the FILE*.
1608 Returns XML_NO_ERROR (0) on success, or
1611 XMLError
SaveFile( FILE* fp
, bool compact
= false );
1613 bool ProcessEntities() const {
1614 return _processEntities
;
1616 Whitespace
WhitespaceMode() const {
1621 Returns true if this document has a leading Byte Order Mark of UTF8.
1623 bool HasBOM() const {
1626 /** Sets whether to write the BOM when writing the file.
1628 void SetBOM( bool useBOM
) {
1632 /** Return the root element of DOM. Equivalent to FirstChildElement().
1633 To get the first node, use FirstChild().
1635 XMLElement
* RootElement() {
1636 return FirstChildElement();
1638 const XMLElement
* RootElement() const {
1639 return FirstChildElement();
1642 /** Print the Document. If the Printer is not provided, it will
1643 print to stdout. If you provide Printer, this can print to a file:
1645 XMLPrinter printer( fp );
1646 doc.Print( &printer );
1649 Or you can use a printer to print to memory:
1652 doc.Print( &printer );
1653 // printer.CStr() has a const char* to the XML
1656 void Print( XMLPrinter
* streamer
=0 ) const;
1657 virtual bool Accept( XMLVisitor
* visitor
) const;
1660 Create a new Element associated with
1661 this Document. The memory for the Element
1662 is managed by the Document.
1664 XMLElement
* NewElement( const char* name
);
1666 Create a new Comment associated with
1667 this Document. The memory for the Comment
1668 is managed by the Document.
1670 XMLComment
* NewComment( const char* comment
);
1672 Create a new Text associated with
1673 this Document. The memory for the Text
1674 is managed by the Document.
1676 XMLText
* NewText( const char* text
);
1678 Create a new Declaration associated with
1679 this Document. The memory for the object
1680 is managed by the Document.
1682 If the 'text' param is null, the standard
1683 declaration is used.:
1685 <?xml version="1.0" encoding="UTF-8"?>
1688 XMLDeclaration
* NewDeclaration( const char* text
=0 );
1690 Create a new Unknown associated with
1691 this Document. The memory for the object
1692 is managed by the Document.
1694 XMLUnknown
* NewUnknown( const char* text
);
1697 Delete a node associated with this document.
1698 It will be unlinked from the DOM.
1700 void DeleteNode( XMLNode
* node
);
1702 void SetError( XMLError error
, const char* str1
, const char* str2
);
1704 /// Return true if there was an error parsing the document.
1705 bool Error() const {
1706 return _errorID
!= XML_NO_ERROR
;
1708 /// Return the errorID.
1709 XMLError
ErrorID() const {
1712 const char* ErrorName() const;
1714 /// Return a possibly helpful diagnostic location or string.
1715 const char* GetErrorStr1() const {
1718 /// Return a possibly helpful secondary diagnostic location or string.
1719 const char* GetErrorStr2() const {
1722 /// If there is an error, print it to stdout.
1723 void PrintError() const;
1725 /// Clear the document, resetting it to the initial state.
1729 char* Identify( char* p
, XMLNode
** node
);
1731 virtual XMLNode
* ShallowClone( XMLDocument
* /*document*/ ) const {
1734 virtual bool ShallowEqual( const XMLNode
* /*compare*/ ) const {
1739 XMLDocument( const XMLDocument
& ); // not supported
1740 void operator=( const XMLDocument
& ); // not supported
1743 bool _processEntities
;
1745 Whitespace _whitespace
;
1746 const char* _errorStr1
;
1747 const char* _errorStr2
;
1750 MemPoolT
< sizeof(XMLElement
) > _elementPool
;
1751 MemPoolT
< sizeof(XMLAttribute
) > _attributePool
;
1752 MemPoolT
< sizeof(XMLText
) > _textPool
;
1753 MemPoolT
< sizeof(XMLComment
) > _commentPool
;
1755 static const char* _errorNames
[XML_ERROR_COUNT
];
1762 A XMLHandle is a class that wraps a node pointer with null checks; this is
1763 an incredibly useful thing. Note that XMLHandle is not part of the TinyXML-2
1764 DOM structure. It is a separate utility class.
1769 <Element attributeA = "valueA">
1770 <Child attributeB = "value1" />
1771 <Child attributeB = "value2" />
1776 Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very
1777 easy to write a *lot* of code that looks like:
1780 XMLElement* root = document.FirstChildElement( "Document" );
1783 XMLElement* element = root->FirstChildElement( "Element" );
1786 XMLElement* child = element->FirstChildElement( "Child" );
1789 XMLElement* child2 = child->NextSiblingElement( "Child" );
1792 // Finally do something useful.
1795 And that doesn't even cover "else" cases. XMLHandle addresses the verbosity
1796 of such code. A XMLHandle checks for null pointers so it is perfectly safe
1800 XMLHandle docHandle( &document );
1801 XMLElement* child2 = docHandle.FirstChildElement( "Document" ).FirstChildElement( "Element" ).FirstChildElement().NextSiblingElement();
1804 // do something useful
1807 Which is MUCH more concise and useful.
1809 It is also safe to copy handles - internally they are nothing more than node pointers.
1811 XMLHandle handleCopy = handle;
1814 See also XMLConstHandle, which is the same as XMLHandle, but operates on const objects.
1816 class TINYXML2_LIB XMLHandle
1819 /// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
1820 XMLHandle( XMLNode
* node
) {
1823 /// Create a handle from a node.
1824 XMLHandle( XMLNode
& node
) {
1827 /// Copy constructor
1828 XMLHandle( const XMLHandle
& ref
) {
1832 XMLHandle
& operator=( const XMLHandle
& ref
) {
1837 /// Get the first child of this handle.
1838 XMLHandle
FirstChild() {
1839 return XMLHandle( _node
? _node
->FirstChild() : 0 );
1841 /// Get the first child element of this handle.
1842 XMLHandle
FirstChildElement( const char* value
=0 ) {
1843 return XMLHandle( _node
? _node
->FirstChildElement( value
) : 0 );
1845 /// Get the last child of this handle.
1846 XMLHandle
LastChild() {
1847 return XMLHandle( _node
? _node
->LastChild() : 0 );
1849 /// Get the last child element of this handle.
1850 XMLHandle
LastChildElement( const char* _value
=0 ) {
1851 return XMLHandle( _node
? _node
->LastChildElement( _value
) : 0 );
1853 /// Get the previous sibling of this handle.
1854 XMLHandle
PreviousSibling() {
1855 return XMLHandle( _node
? _node
->PreviousSibling() : 0 );
1857 /// Get the previous sibling element of this handle.
1858 XMLHandle
PreviousSiblingElement( const char* _value
=0 ) {
1859 return XMLHandle( _node
? _node
->PreviousSiblingElement( _value
) : 0 );
1861 /// Get the next sibling of this handle.
1862 XMLHandle
NextSibling() {
1863 return XMLHandle( _node
? _node
->NextSibling() : 0 );
1865 /// Get the next sibling element of this handle.
1866 XMLHandle
NextSiblingElement( const char* _value
=0 ) {
1867 return XMLHandle( _node
? _node
->NextSiblingElement( _value
) : 0 );
1870 /// Safe cast to XMLNode. This can return null.
1874 /// Safe cast to XMLElement. This can return null.
1875 XMLElement
* ToElement() {
1876 return ( ( _node
== 0 ) ? 0 : _node
->ToElement() );
1878 /// Safe cast to XMLText. This can return null.
1880 return ( ( _node
== 0 ) ? 0 : _node
->ToText() );
1882 /// Safe cast to XMLUnknown. This can return null.
1883 XMLUnknown
* ToUnknown() {
1884 return ( ( _node
== 0 ) ? 0 : _node
->ToUnknown() );
1886 /// Safe cast to XMLDeclaration. This can return null.
1887 XMLDeclaration
* ToDeclaration() {
1888 return ( ( _node
== 0 ) ? 0 : _node
->ToDeclaration() );
1897 A variant of the XMLHandle class for working with const XMLNodes and Documents. It is the
1898 same in all regards, except for the 'const' qualifiers. See XMLHandle for API.
1900 class TINYXML2_LIB XMLConstHandle
1903 XMLConstHandle( const XMLNode
* node
) {
1906 XMLConstHandle( const XMLNode
& node
) {
1909 XMLConstHandle( const XMLConstHandle
& ref
) {
1913 XMLConstHandle
& operator=( const XMLConstHandle
& ref
) {
1918 const XMLConstHandle
FirstChild() const {
1919 return XMLConstHandle( _node
? _node
->FirstChild() : 0 );
1921 const XMLConstHandle
FirstChildElement( const char* value
=0 ) const {
1922 return XMLConstHandle( _node
? _node
->FirstChildElement( value
) : 0 );
1924 const XMLConstHandle
LastChild() const {
1925 return XMLConstHandle( _node
? _node
->LastChild() : 0 );
1927 const XMLConstHandle
LastChildElement( const char* _value
=0 ) const {
1928 return XMLConstHandle( _node
? _node
->LastChildElement( _value
) : 0 );
1930 const XMLConstHandle
PreviousSibling() const {
1931 return XMLConstHandle( _node
? _node
->PreviousSibling() : 0 );
1933 const XMLConstHandle
PreviousSiblingElement( const char* _value
=0 ) const {
1934 return XMLConstHandle( _node
? _node
->PreviousSiblingElement( _value
) : 0 );
1936 const XMLConstHandle
NextSibling() const {
1937 return XMLConstHandle( _node
? _node
->NextSibling() : 0 );
1939 const XMLConstHandle
NextSiblingElement( const char* _value
=0 ) const {
1940 return XMLConstHandle( _node
? _node
->NextSiblingElement( _value
) : 0 );
1944 const XMLNode
* ToNode() const {
1947 const XMLElement
* ToElement() const {
1948 return ( ( _node
== 0 ) ? 0 : _node
->ToElement() );
1950 const XMLText
* ToText() const {
1951 return ( ( _node
== 0 ) ? 0 : _node
->ToText() );
1953 const XMLUnknown
* ToUnknown() const {
1954 return ( ( _node
== 0 ) ? 0 : _node
->ToUnknown() );
1956 const XMLDeclaration
* ToDeclaration() const {
1957 return ( ( _node
== 0 ) ? 0 : _node
->ToDeclaration() );
1961 const XMLNode
* _node
;
1966 Printing functionality. The XMLPrinter gives you more
1967 options than the XMLDocument::Print() method.
1971 -# Print to a file you provide.
1972 -# Print XML without a XMLDocument.
1978 doc.Print( &printer );
1979 SomeFunction( printer.CStr() );
1984 You provide the file pointer.
1986 XMLPrinter printer( fp );
1987 doc.Print( &printer );
1990 Print without a XMLDocument
1992 When loading, an XML parser is very useful. However, sometimes
1993 when saving, it just gets in the way. The code is often set up
1994 for streaming, and constructing the DOM is just overhead.
1996 The Printer supports the streaming case. The following code
1997 prints out a trivially simple XML file without ever creating
2001 XMLPrinter printer( fp );
2002 printer.OpenElement( "foo" );
2003 printer.PushAttribute( "foo", "bar" );
2004 printer.CloseElement();
2007 class TINYXML2_LIB XMLPrinter
: public XMLVisitor
2010 /** Construct the printer. If the FILE* is specified,
2011 this will print to the FILE. Else it will print
2012 to memory, and the result is available in CStr().
2013 If 'compact' is set to true, then output is created
2014 with only required whitespace and newlines.
2016 XMLPrinter( FILE* file
=0, bool compact
= false, int depth
= 0 );
2017 virtual ~XMLPrinter() {}
2019 /** If streaming, write the BOM and declaration. */
2020 void PushHeader( bool writeBOM
, bool writeDeclaration
);
2021 /** If streaming, start writing an element.
2022 The element must be closed with CloseElement()
2024 void OpenElement( const char* name
, bool compactMode
=false );
2025 /// If streaming, add an attribute to an open element.
2026 void PushAttribute( const char* name
, const char* value
);
2027 void PushAttribute( const char* name
, int value
);
2028 void PushAttribute( const char* name
, unsigned value
);
2029 void PushAttribute( const char* name
, bool value
);
2030 void PushAttribute( const char* name
, double value
);
2031 /// If streaming, close the Element.
2032 virtual void CloseElement( bool compactMode
=false );
2034 /// Add a text node.
2035 void PushText( const char* text
, bool cdata
=false );
2036 /// Add a text node from an integer.
2037 void PushText( int value
);
2038 /// Add a text node from an unsigned.
2039 void PushText( unsigned value
);
2040 /// Add a text node from a bool.
2041 void PushText( bool value
);
2042 /// Add a text node from a float.
2043 void PushText( float value
);
2044 /// Add a text node from a double.
2045 void PushText( double value
);
2048 void PushComment( const char* comment
);
2050 void PushDeclaration( const char* value
);
2051 void PushUnknown( const char* value
);
2053 virtual bool VisitEnter( const XMLDocument
& /*doc*/ );
2054 virtual bool VisitExit( const XMLDocument
& /*doc*/ ) {
2058 virtual bool VisitEnter( const XMLElement
& element
, const XMLAttribute
* attribute
);
2059 virtual bool VisitExit( const XMLElement
& element
);
2061 virtual bool Visit( const XMLText
& text
);
2062 virtual bool Visit( const XMLComment
& comment
);
2063 virtual bool Visit( const XMLDeclaration
& declaration
);
2064 virtual bool Visit( const XMLUnknown
& unknown
);
2067 If in print to memory mode, return a pointer to
2068 the XML file in memory.
2070 const char* CStr() const {
2071 return _buffer
.Mem();
2074 If in print to memory mode, return the size
2075 of the XML file in memory. (Note the size returned
2076 includes the terminating null.)
2078 int CStrSize() const {
2079 return _buffer
.Size();
2082 If in print to memory mode, reset the buffer to the
2085 void ClearBuffer() {
2091 virtual bool CompactMode( const XMLElement
& ) { return _compactMode
; }
2093 /** Prints out the space before an element. You may override to change
2094 the space and tabs used. A PrintSpace() override should call Print().
2096 virtual void PrintSpace( int depth
);
2097 void Print( const char* format
, ... );
2099 void SealElementIfJustOpened();
2100 bool _elementJustOpened
;
2101 DynArray
< const char*, 10 > _stack
;
2104 void PrintString( const char*, bool restrictedEntitySet
); // prints out, after detecting entities.
2110 bool _processEntities
;
2117 bool _entityFlag
[ENTITY_RANGE
];
2118 bool _restrictedEntityFlag
[ENTITY_RANGE
];
2120 DynArray
< char, 20 > _buffer
;
2126 #if defined(_MSC_VER)
2127 # pragma warning(pop)
2130 #endif // TINYXML2_INCLUDED