2 Original code by Lee Thomason (www.grinninglizard.com)
\r
4 This software is provided 'as-is', without any express or implied
\r
5 warranty. In no event will the authors be held liable for any
\r
6 damages arising from the use of this software.
\r
8 Permission is granted to anyone to use this software for any
\r
9 purpose, including commercial applications, and to alter it and
\r
10 redistribute it freely, subject to the following restrictions:
\r
12 1. The origin of this software must not be misrepresented; you must
\r
13 not claim that you wrote the original software. If you use this
\r
14 software in a product, an acknowledgment in the product documentation
\r
15 would be appreciated but is not required.
\r
17 2. Altered source versions must be plainly marked as such, and
\r
18 must not be misrepresented as being the original software.
\r
20 3. This notice may not be removed or altered from any source
\r
24 #ifndef TINYXML2_INCLUDED
\r
25 #define TINYXML2_INCLUDED
\r
27 #if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__)
\r
29 # include <limits.h>
\r
31 # include <stdlib.h>
\r
32 # include <string.h>
\r
42 TODO: intern strings instead of allocation.
\r
46 g++ -Wall -DDEBUG tinyxml2.cpp xmltest.cpp -o gccxmltest.exe
\r
48 Formatting, Artistic Style:
\r
49 AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h
\r
52 #if defined( _DEBUG ) || defined( DEBUG ) || defined (__DEBUG__)
\r
59 # pragma warning(push)
\r
60 # pragma warning(disable: 4251)
\r
64 # ifdef TINYXML2_EXPORT
\r
65 # define TINYXML2_LIB __declspec(dllexport)
\r
66 # elif defined(TINYXML2_IMPORT)
\r
67 # define TINYXML2_LIB __declspec(dllimport)
\r
69 # define TINYXML2_LIB
\r
72 # define TINYXML2_LIB
\r
77 # if defined(_MSC_VER)
\r
78 # // "(void)0," is for suppressing C4127 warning in "assert(false)", "assert(true)" and the like
\r
79 # define TIXMLASSERT( x ) if ( !((void)0,(x))) { __debugbreak(); }
\r
80 # elif defined (ANDROID_NDK)
\r
81 # include <android/log.h>
\r
82 # define TIXMLASSERT( x ) if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); }
\r
84 # include <assert.h>
\r
85 # define TIXMLASSERT assert
\r
88 # define TIXMLASSERT( x ) {}
\r
92 /* Versioning, past 1.0.14:
\r
95 static const int TIXML2_MAJOR_VERSION = 3;
\r
96 static const int TIXML2_MINOR_VERSION = 0;
\r
97 static const int TIXML2_PATCH_VERSION = 0;
\r
103 class XMLAttribute;
\r
106 class XMLDeclaration;
\r
111 A class that wraps strings. Normally stores the start and end
\r
112 pointers into the XML file itself, and will apply normalization
\r
113 and entity translation if actually read. Can also store (and memory
\r
114 manage) a traditional char[]
\r
120 NEEDS_ENTITY_PROCESSING = 0x01,
\r
121 NEEDS_NEWLINE_NORMALIZATION = 0x02,
\r
122 NEEDS_WHITESPACE_COLLAPSING = 0x04,
\r
124 TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
\r
125 TEXT_ELEMENT_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
\r
126 ATTRIBUTE_NAME = 0,
\r
127 ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
\r
128 ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
\r
129 COMMENT = NEEDS_NEWLINE_NORMALIZATION
\r
132 StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {}
\r
135 void Set( char* start, char* end, int flags ) {
\r
139 _flags = flags | NEEDS_FLUSH;
\r
142 const char* GetStr();
\r
144 bool Empty() const {
\r
145 return _start == _end;
\r
148 void SetInternedStr( const char* str ) {
\r
150 _start = const_cast<char*>(str);
\r
153 void SetStr( const char* str, int flags=0 );
\r
155 char* ParseText( char* in, const char* endTag, int strFlags );
\r
156 char* ParseName( char* in );
\r
158 void TransferTo( StrPair* other );
\r
162 void CollapseWhitespace();
\r
165 NEEDS_FLUSH = 0x100,
\r
166 NEEDS_DELETE = 0x200
\r
173 StrPair( const StrPair& other ); // not supported
\r
174 void operator=( StrPair& other ); // not supported, use TransferTo()
\r
179 A dynamic array of Plain Old Data. Doesn't support constructors, etc.
\r
180 Has a small initial memory pool, so that low or no usage will not
\r
181 cause a call to new/delete
\r
183 template <class T, int INITIAL_SIZE>
\r
189 _allocated = INITIAL_SIZE;
\r
194 if ( _mem != _pool ) {
\r
204 TIXMLASSERT( _size < INT_MAX );
\r
205 EnsureCapacity( _size+1 );
\r
209 T* PushArr( int count ) {
\r
210 TIXMLASSERT( count >= 0 );
\r
211 TIXMLASSERT( _size <= INT_MAX - count );
\r
212 EnsureCapacity( _size+count );
\r
213 T* ret = &_mem[_size];
\r
219 TIXMLASSERT( _size > 0 );
\r
220 return _mem[--_size];
\r
223 void PopArr( int count ) {
\r
224 TIXMLASSERT( _size >= count );
\r
228 bool Empty() const {
\r
232 T& operator[](int i) {
\r
233 TIXMLASSERT( i>= 0 && i < _size );
\r
237 const T& operator[](int i) const {
\r
238 TIXMLASSERT( i>= 0 && i < _size );
\r
242 const T& PeekTop() const {
\r
243 TIXMLASSERT( _size > 0 );
\r
244 return _mem[ _size - 1];
\r
248 TIXMLASSERT( _size >= 0 );
\r
252 int Capacity() const {
\r
253 TIXMLASSERT( _allocated >= INITIAL_SIZE );
\r
257 const T* Mem() const {
\r
258 TIXMLASSERT( _mem );
\r
263 TIXMLASSERT( _mem );
\r
268 DynArray( const DynArray& ); // not supported
\r
269 void operator=( const DynArray& ); // not supported
\r
271 void EnsureCapacity( int cap ) {
\r
272 TIXMLASSERT( cap > 0 );
\r
273 if ( cap > _allocated ) {
\r
274 TIXMLASSERT( cap <= INT_MAX / 2 );
\r
275 int newAllocated = cap * 2;
\r
276 T* newMem = new T[newAllocated];
\r
277 memcpy( newMem, _mem, sizeof(T)*_size ); // warning: not using constructors, only works for PODs
\r
278 if ( _mem != _pool ) {
\r
282 _allocated = newAllocated;
\r
287 T _pool[INITIAL_SIZE];
\r
288 int _allocated; // objects allocated
\r
289 int _size; // number objects in use
\r
294 Parent virtual class of a pool for fast allocation
\r
295 and deallocation of objects.
\r
301 virtual ~MemPool() {}
\r
303 virtual int ItemSize() const = 0;
\r
304 virtual void* Alloc() = 0;
\r
305 virtual void Free( void* ) = 0;
\r
306 virtual void SetTracked() = 0;
\r
307 virtual void Clear() = 0;
\r
312 Template child class to create pools of the correct type.
\r
314 template< int SIZE >
\r
315 class MemPoolT : public MemPool
\r
318 MemPoolT() : _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {}
\r
324 // Delete the blocks.
\r
325 while( !_blockPtrs.Empty()) {
\r
326 Block* b = _blockPtrs.Pop();
\r
330 _currentAllocs = 0;
\r
336 virtual int ItemSize() const {
\r
339 int CurrentAllocs() const {
\r
340 return _currentAllocs;
\r
343 virtual void* Alloc() {
\r
345 // Need a new block.
\r
346 Block* block = new Block();
\r
347 _blockPtrs.Push( block );
\r
349 for( int i=0; i<COUNT-1; ++i ) {
\r
350 block->chunk[i].next = &block->chunk[i+1];
\r
352 block->chunk[COUNT-1].next = 0;
\r
353 _root = block->chunk;
\r
355 void* result = _root;
\r
356 _root = _root->next;
\r
359 if ( _currentAllocs > _maxAllocs ) {
\r
360 _maxAllocs = _currentAllocs;
\r
367 virtual void Free( void* mem ) {
\r
372 Chunk* chunk = static_cast<Chunk*>( mem );
\r
374 memset( chunk, 0xfe, sizeof(Chunk) );
\r
376 chunk->next = _root;
\r
379 void Trace( const char* name ) {
\r
380 printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n",
\r
381 name, _maxAllocs, _maxAllocs*SIZE/1024, _currentAllocs, SIZE, _nAllocs, _blockPtrs.Size() );
\r
384 void SetTracked() {
\r
388 int Untracked() const {
\r
389 return _nUntracked;
\r
392 // This number is perf sensitive. 4k seems like a good tradeoff on my machine.
\r
393 // The test file is large, 170k.
\r
394 // Release: VS2010 gcc(no opt)
\r
401 enum { COUNT = (4*1024)/SIZE }; // Some compilers do not accept to use COUNT in private part if COUNT is private
\r
404 MemPoolT( const MemPoolT& ); // not supported
\r
405 void operator=( const MemPoolT& ); // not supported
\r
412 Chunk chunk[COUNT];
\r
414 DynArray< Block*, 10 > _blockPtrs;
\r
417 int _currentAllocs;
\r
426 Implements the interface to the "Visitor pattern" (see the Accept() method.)
\r
427 If you call the Accept() method, it requires being passed a XMLVisitor
\r
428 class to handle callbacks. For nodes that contain other nodes (Document, Element)
\r
429 you will get called with a VisitEnter/VisitExit pair. Nodes that are always leafs
\r
430 are simply called with Visit().
\r
432 If you return 'true' from a Visit method, recursive parsing will continue. If you return
\r
433 false, <b>no children of this node or its siblings</b> will be visited.
\r
435 All flavors of Visit methods have a default implementation that returns 'true' (continue
\r
436 visiting). You need to only override methods that are interesting to you.
\r
438 Generally Accept() is called on the XMLDocument, although all nodes support visiting.
\r
440 You should never change the document from a callback.
\r
442 @sa XMLNode::Accept()
\r
444 class TINYXML2_LIB XMLVisitor
\r
447 virtual ~XMLVisitor() {}
\r
449 /// Visit a document.
\r
450 virtual bool VisitEnter( const XMLDocument& /*doc*/ ) {
\r
453 /// Visit a document.
\r
454 virtual bool VisitExit( const XMLDocument& /*doc*/ ) {
\r
458 /// Visit an element.
\r
459 virtual bool VisitEnter( const XMLElement& /*element*/, const XMLAttribute* /*firstAttribute*/ ) {
\r
462 /// Visit an element.
\r
463 virtual bool VisitExit( const XMLElement& /*element*/ ) {
\r
467 /// Visit a declaration.
\r
468 virtual bool Visit( const XMLDeclaration& /*declaration*/ ) {
\r
471 /// Visit a text node.
\r
472 virtual bool Visit( const XMLText& /*text*/ ) {
\r
475 /// Visit a comment node.
\r
476 virtual bool Visit( const XMLComment& /*comment*/ ) {
\r
479 /// Visit an unknown node.
\r
480 virtual bool Visit( const XMLUnknown& /*unknown*/ ) {
\r
485 // WARNING: must match XMLDocument::_errorNames[]
\r
490 XML_WRONG_ATTRIBUTE_TYPE,
\r
491 XML_ERROR_FILE_NOT_FOUND,
\r
492 XML_ERROR_FILE_COULD_NOT_BE_OPENED,
\r
493 XML_ERROR_FILE_READ_ERROR,
\r
494 XML_ERROR_ELEMENT_MISMATCH,
\r
495 XML_ERROR_PARSING_ELEMENT,
\r
496 XML_ERROR_PARSING_ATTRIBUTE,
\r
497 XML_ERROR_IDENTIFYING_TAG,
\r
498 XML_ERROR_PARSING_TEXT,
\r
499 XML_ERROR_PARSING_CDATA,
\r
500 XML_ERROR_PARSING_COMMENT,
\r
501 XML_ERROR_PARSING_DECLARATION,
\r
502 XML_ERROR_PARSING_UNKNOWN,
\r
503 XML_ERROR_EMPTY_DOCUMENT,
\r
504 XML_ERROR_MISMATCHED_ELEMENT,
\r
506 XML_CAN_NOT_CONVERT_TEXT,
\r
514 Utility functionality.
\r
519 static const char* SkipWhiteSpace( const char* p ) {
\r
521 while( IsWhiteSpace(*p) ) {
\r
527 static char* SkipWhiteSpace( char* p ) {
\r
528 return const_cast<char*>( SkipWhiteSpace( const_cast<const char*>(p) ) );
\r
531 // Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't
\r
532 // correct, but simple, and usually works.
\r
533 static bool IsWhiteSpace( char p ) {
\r
534 return !IsUTF8Continuation(p) && isspace( static_cast<unsigned char>(p) );
\r
537 inline static bool IsNameStartChar( unsigned char ch ) {
\r
539 // This is a heuristic guess in attempt to not implement Unicode-aware isalpha()
\r
542 if ( isalpha( ch ) ) {
\r
545 return ch == ':' || ch == '_';
\r
548 inline static bool IsNameChar( unsigned char ch ) {
\r
549 return IsNameStartChar( ch )
\r
555 inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX ) {
\r
559 return strncmp( p, q, nChar ) == 0;
\r
562 inline static bool IsUTF8Continuation( char p ) {
\r
563 return ( p & 0x80 ) != 0;
\r
566 static const char* ReadBOM( const char* p, bool* hasBOM );
\r
567 // p is the starting location,
\r
568 // the UTF-8 value of the entity will be placed in value, and length filled in.
\r
569 static const char* GetCharacterRef( const char* p, char* value, int* length );
\r
570 static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
\r
572 // converts primitive types to strings
\r
573 static void ToStr( int v, char* buffer, int bufferSize );
\r
574 static void ToStr( unsigned v, char* buffer, int bufferSize );
\r
575 static void ToStr( bool v, char* buffer, int bufferSize );
\r
576 static void ToStr( float v, char* buffer, int bufferSize );
\r
577 static void ToStr( double v, char* buffer, int bufferSize );
\r
579 // converts strings to primitive types
\r
580 static bool ToInt( const char* str, int* value );
\r
581 static bool ToUnsigned( const char* str, unsigned* value );
\r
582 static bool ToBool( const char* str, bool* value );
\r
583 static bool ToFloat( const char* str, float* value );
\r
584 static bool ToDouble( const char* str, double* value );
\r
588 /** XMLNode is a base class for every object that is in the
\r
589 XML Document Object Model (DOM), except XMLAttributes.
\r
590 Nodes have siblings, a parent, and children which can
\r
591 be navigated. A node is always in a XMLDocument.
\r
592 The type of a XMLNode can be queried, and it can
\r
593 be cast to its more defined type.
\r
595 A XMLDocument allocates memory for all its Nodes.
\r
596 When the XMLDocument gets deleted, all its Nodes
\r
597 will also be deleted.
\r
600 A Document can contain: Element (container or leaf)
\r
603 Declaration( leaf )
\r
605 An Element can contain: Element (container or leaf)
\r
607 Attributes (not on tree)
\r
613 class TINYXML2_LIB XMLNode
\r
615 friend class XMLDocument;
\r
616 friend class XMLElement;
\r
619 /// Get the XMLDocument that owns this XMLNode.
\r
620 const XMLDocument* GetDocument() const {
\r
621 TIXMLASSERT( _document );
\r
624 /// Get the XMLDocument that owns this XMLNode.
\r
625 XMLDocument* GetDocument() {
\r
626 TIXMLASSERT( _document );
\r
630 /// Safely cast to an Element, or null.
\r
631 virtual XMLElement* ToElement() {
\r
634 /// Safely cast to Text, or null.
\r
635 virtual XMLText* ToText() {
\r
638 /// Safely cast to a Comment, or null.
\r
639 virtual XMLComment* ToComment() {
\r
642 /// Safely cast to a Document, or null.
\r
643 virtual XMLDocument* ToDocument() {
\r
646 /// Safely cast to a Declaration, or null.
\r
647 virtual XMLDeclaration* ToDeclaration() {
\r
650 /// Safely cast to an Unknown, or null.
\r
651 virtual XMLUnknown* ToUnknown() {
\r
655 virtual const XMLElement* ToElement() const {
\r
658 virtual const XMLText* ToText() const {
\r
661 virtual const XMLComment* ToComment() const {
\r
664 virtual const XMLDocument* ToDocument() const {
\r
667 virtual const XMLDeclaration* ToDeclaration() const {
\r
670 virtual const XMLUnknown* ToUnknown() const {
\r
674 /** The meaning of 'value' changes for the specific type.
\r
676 Document: empty (NULL is returned, not an empty string)
\r
677 Element: name of the element
\r
678 Comment: the comment text
\r
679 Unknown: the tag contents
\r
680 Text: the text string
\r
683 const char* Value() const;
\r
685 /** Set the Value of an XML node.
\r
688 void SetValue( const char* val, bool staticMem=false );
\r
690 /// Get the parent of this node on the DOM.
\r
691 const XMLNode* Parent() const {
\r
695 XMLNode* Parent() {
\r
699 /// Returns true if this node has no children.
\r
700 bool NoChildren() const {
\r
701 return !_firstChild;
\r
704 /// Get the first child node, or null if none exists.
\r
705 const XMLNode* FirstChild() const {
\r
706 return _firstChild;
\r
709 XMLNode* FirstChild() {
\r
710 return _firstChild;
\r
713 /** Get the first child element, or optionally the first child
\r
714 element with the specified name.
\r
716 const XMLElement* FirstChildElement( const char* name = 0 ) const;
\r
718 XMLElement* FirstChildElement( const char* name = 0 ) {
\r
719 return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->FirstChildElement( name ));
\r
722 /// Get the last child node, or null if none exists.
\r
723 const XMLNode* LastChild() const {
\r
727 XMLNode* LastChild() {
\r
731 /** Get the last child element or optionally the last child
\r
732 element with the specified name.
\r
734 const XMLElement* LastChildElement( const char* name = 0 ) const;
\r
736 XMLElement* LastChildElement( const char* name = 0 ) {
\r
737 return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->LastChildElement(name) );
\r
740 /// Get the previous (left) sibling node of this node.
\r
741 const XMLNode* PreviousSibling() const {
\r
745 XMLNode* PreviousSibling() {
\r
749 /// Get the previous (left) sibling element of this node, with an optionally supplied name.
\r
750 const XMLElement* PreviousSiblingElement( const char* name = 0 ) const ;
\r
752 XMLElement* PreviousSiblingElement( const char* name = 0 ) {
\r
753 return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->PreviousSiblingElement( name ) );
\r
756 /// Get the next (right) sibling node of this node.
\r
757 const XMLNode* NextSibling() const {
\r
761 XMLNode* NextSibling() {
\r
765 /// Get the next (right) sibling element of this node, with an optionally supplied name.
\r
766 const XMLElement* NextSiblingElement( const char* name = 0 ) const;
\r
768 XMLElement* NextSiblingElement( const char* name = 0 ) {
\r
769 return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->NextSiblingElement( name ) );
\r
773 Add a child node as the last (right) child.
\r
774 If the child node is already part of the document,
\r
775 it is moved from its old location to the new location.
\r
776 Returns the addThis argument or 0 if the node does not
\r
777 belong to the same document.
\r
779 XMLNode* InsertEndChild( XMLNode* addThis );
\r
781 XMLNode* LinkEndChild( XMLNode* addThis ) {
\r
782 return InsertEndChild( addThis );
\r
785 Add a child node as the first (left) child.
\r
786 If the child node is already part of the document,
\r
787 it is moved from its old location to the new location.
\r
788 Returns the addThis argument or 0 if the node does not
\r
789 belong to the same document.
\r
791 XMLNode* InsertFirstChild( XMLNode* addThis );
\r
793 Add a node after the specified child node.
\r
794 If the child node is already part of the document,
\r
795 it is moved from its old location to the new location.
\r
796 Returns the addThis argument or 0 if the afterThis node
\r
797 is not a child of this node, or if the node does not
\r
798 belong to the same document.
\r
800 XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis );
\r
803 Delete all the children of this node.
\r
805 void DeleteChildren();
\r
808 Delete a child of this node.
\r
810 void DeleteChild( XMLNode* node );
\r
813 Make a copy of this node, but not its children.
\r
814 You may pass in a Document pointer that will be
\r
815 the owner of the new Node. If the 'document' is
\r
816 null, then the node returned will be allocated
\r
817 from the current Document. (this->GetDocument())
\r
819 Note: if called on a XMLDocument, this will return null.
\r
821 virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0;
\r
824 Test if 2 nodes are the same, but don't test children.
\r
825 The 2 nodes do not need to be in the same Document.
\r
827 Note: if called on a XMLDocument, this will return false.
\r
829 virtual bool ShallowEqual( const XMLNode* compare ) const = 0;
\r
831 /** Accept a hierarchical visit of the nodes in the TinyXML-2 DOM. Every node in the
\r
832 XML tree will be conditionally visited and the host will be called back
\r
833 via the XMLVisitor interface.
\r
835 This is essentially a SAX interface for TinyXML-2. (Note however it doesn't re-parse
\r
836 the XML for the callbacks, so the performance of TinyXML-2 is unchanged by using this
\r
837 interface versus any other.)
\r
839 The interface has been based on ideas from:
\r
841 - http://www.saxproject.org/
\r
842 - http://c2.com/cgi/wiki?HierarchicalVisitorPattern
\r
844 Which are both good references for "visiting".
\r
846 An example of using Accept():
\r
848 XMLPrinter printer;
\r
849 tinyxmlDoc.Accept( &printer );
\r
850 const char* xmlcstr = printer.CStr();
\r
853 virtual bool Accept( XMLVisitor* visitor ) const = 0;
\r
856 XMLNode( XMLDocument* );
\r
857 virtual ~XMLNode();
\r
859 virtual char* ParseDeep( char*, StrPair* );
\r
861 XMLDocument* _document;
\r
863 mutable StrPair _value;
\r
865 XMLNode* _firstChild;
\r
866 XMLNode* _lastChild;
\r
873 void Unlink( XMLNode* child );
\r
874 static void DeleteNode( XMLNode* node );
\r
875 void InsertChildPreamble( XMLNode* insertThis ) const;
\r
877 XMLNode( const XMLNode& ); // not supported
\r
878 XMLNode& operator=( const XMLNode& ); // not supported
\r
884 Note that a text node can have child element nodes, for example:
\r
886 <root>This is <b>bold</b></root>
\r
889 A text node can have 2 ways to output the next. "normal" output
\r
890 and CDATA. It will default to the mode it was parsed from the XML file and
\r
891 you generally want to leave it alone, but you can change the output mode with
\r
892 SetCData() and query it with CData().
\r
894 class TINYXML2_LIB XMLText : public XMLNode
\r
896 friend class XMLBase;
\r
897 friend class XMLDocument;
\r
899 virtual bool Accept( XMLVisitor* visitor ) const;
\r
901 virtual XMLText* ToText() {
\r
904 virtual const XMLText* ToText() const {
\r
908 /// Declare whether this should be CDATA or standard text.
\r
909 void SetCData( bool isCData ) {
\r
910 _isCData = isCData;
\r
912 /// Returns true if this is a CDATA text element.
\r
913 bool CData() const {
\r
917 virtual XMLNode* ShallowClone( XMLDocument* document ) const;
\r
918 virtual bool ShallowEqual( const XMLNode* compare ) const;
\r
921 XMLText( XMLDocument* doc ) : XMLNode( doc ), _isCData( false ) {}
\r
922 virtual ~XMLText() {}
\r
924 char* ParseDeep( char*, StrPair* endTag );
\r
929 XMLText( const XMLText& ); // not supported
\r
930 XMLText& operator=( const XMLText& ); // not supported
\r
934 /** An XML Comment. */
\r
935 class TINYXML2_LIB XMLComment : public XMLNode
\r
937 friend class XMLDocument;
\r
939 virtual XMLComment* ToComment() {
\r
942 virtual const XMLComment* ToComment() const {
\r
946 virtual bool Accept( XMLVisitor* visitor ) const;
\r
948 virtual XMLNode* ShallowClone( XMLDocument* document ) const;
\r
949 virtual bool ShallowEqual( const XMLNode* compare ) const;
\r
952 XMLComment( XMLDocument* doc );
\r
953 virtual ~XMLComment();
\r
955 char* ParseDeep( char*, StrPair* endTag );
\r
958 XMLComment( const XMLComment& ); // not supported
\r
959 XMLComment& operator=( const XMLComment& ); // not supported
\r
963 /** In correct XML the declaration is the first entry in the file.
\r
965 <?xml version="1.0" standalone="yes"?>
\r
968 TinyXML-2 will happily read or write files without a declaration,
\r
971 The text of the declaration isn't interpreted. It is parsed
\r
972 and written as a string.
\r
974 class TINYXML2_LIB XMLDeclaration : public XMLNode
\r
976 friend class XMLDocument;
\r
978 virtual XMLDeclaration* ToDeclaration() {
\r
981 virtual const XMLDeclaration* ToDeclaration() const {
\r
985 virtual bool Accept( XMLVisitor* visitor ) const;
\r
987 virtual XMLNode* ShallowClone( XMLDocument* document ) const;
\r
988 virtual bool ShallowEqual( const XMLNode* compare ) const;
\r
991 XMLDeclaration( XMLDocument* doc );
\r
992 virtual ~XMLDeclaration();
\r
994 char* ParseDeep( char*, StrPair* endTag );
\r
997 XMLDeclaration( const XMLDeclaration& ); // not supported
\r
998 XMLDeclaration& operator=( const XMLDeclaration& ); // not supported
\r
1002 /** Any tag that TinyXML-2 doesn't recognize is saved as an
\r
1003 unknown. It is a tag of text, but should not be modified.
\r
1004 It will be written back to the XML, unchanged, when the file
\r
1007 DTD tags get thrown into XMLUnknowns.
\r
1009 class TINYXML2_LIB XMLUnknown : public XMLNode
\r
1011 friend class XMLDocument;
\r
1013 virtual XMLUnknown* ToUnknown() {
\r
1016 virtual const XMLUnknown* ToUnknown() const {
\r
1020 virtual bool Accept( XMLVisitor* visitor ) const;
\r
1022 virtual XMLNode* ShallowClone( XMLDocument* document ) const;
\r
1023 virtual bool ShallowEqual( const XMLNode* compare ) const;
\r
1026 XMLUnknown( XMLDocument* doc );
\r
1027 virtual ~XMLUnknown();
\r
1029 char* ParseDeep( char*, StrPair* endTag );
\r
1032 XMLUnknown( const XMLUnknown& ); // not supported
\r
1033 XMLUnknown& operator=( const XMLUnknown& ); // not supported
\r
1038 /** An attribute is a name-value pair. Elements have an arbitrary
\r
1039 number of attributes, each with a unique name.
\r
1041 @note The attributes are not XMLNodes. You may only query the
\r
1042 Next() attribute in a list.
\r
1044 class TINYXML2_LIB XMLAttribute
\r
1046 friend class XMLElement;
\r
1048 /// The name of the attribute.
\r
1049 const char* Name() const;
\r
1051 /// The value of the attribute.
\r
1052 const char* Value() const;
\r
1054 /// The next attribute in the list.
\r
1055 const XMLAttribute* Next() const {
\r
1059 /** IntValue interprets the attribute as an integer, and returns the value.
\r
1060 If the value isn't an integer, 0 will be returned. There is no error checking;
\r
1061 use QueryIntValue() if you need error checking.
\r
1063 int IntValue() const {
\r
1065 QueryIntValue( &i );
\r
1068 /// Query as an unsigned integer. See IntValue()
\r
1069 unsigned UnsignedValue() const {
\r
1071 QueryUnsignedValue( &i );
\r
1074 /// Query as a boolean. See IntValue()
\r
1075 bool BoolValue() const {
\r
1077 QueryBoolValue( &b );
\r
1080 /// Query as a double. See IntValue()
\r
1081 double DoubleValue() const {
\r
1083 QueryDoubleValue( &d );
\r
1086 /// Query as a float. See IntValue()
\r
1087 float FloatValue() const {
\r
1089 QueryFloatValue( &f );
\r
1093 /** QueryIntValue interprets the attribute as an integer, and returns the value
\r
1094 in the provided parameter. The function will return XML_NO_ERROR on success,
\r
1095 and XML_WRONG_ATTRIBUTE_TYPE if the conversion is not successful.
\r
1097 XMLError QueryIntValue( int* value ) const;
\r
1098 /// See QueryIntValue
\r
1099 XMLError QueryUnsignedValue( unsigned int* value ) const;
\r
1100 /// See QueryIntValue
\r
1101 XMLError QueryBoolValue( bool* value ) const;
\r
1102 /// See QueryIntValue
\r
1103 XMLError QueryDoubleValue( double* value ) const;
\r
1104 /// See QueryIntValue
\r
1105 XMLError QueryFloatValue( float* value ) const;
\r
1107 /// Set the attribute to a string value.
\r
1108 void SetAttribute( const char* value );
\r
1109 /// Set the attribute to value.
\r
1110 void SetAttribute( int value );
\r
1111 /// Set the attribute to value.
\r
1112 void SetAttribute( unsigned value );
\r
1113 /// Set the attribute to value.
\r
1114 void SetAttribute( bool value );
\r
1115 /// Set the attribute to value.
\r
1116 void SetAttribute( double value );
\r
1117 /// Set the attribute to value.
\r
1118 void SetAttribute( float value );
\r
1121 enum { BUF_SIZE = 200 };
\r
1123 XMLAttribute() : _next( 0 ), _memPool( 0 ) {}
\r
1124 virtual ~XMLAttribute() {}
\r
1126 XMLAttribute( const XMLAttribute& ); // not supported
\r
1127 void operator=( const XMLAttribute& ); // not supported
\r
1128 void SetName( const char* name );
\r
1130 char* ParseDeep( char* p, bool processEntities );
\r
1132 mutable StrPair _name;
\r
1133 mutable StrPair _value;
\r
1134 XMLAttribute* _next;
\r
1135 MemPool* _memPool;
\r
1139 /** The element is a container class. It has a value, the element name,
\r
1140 and can contain other elements, text, comments, and unknowns.
\r
1141 Elements also contain an arbitrary number of attributes.
\r
1143 class TINYXML2_LIB XMLElement : public XMLNode
\r
1145 friend class XMLBase;
\r
1146 friend class XMLDocument;
\r
1148 /// Get the name of an element (which is the Value() of the node.)
\r
1149 const char* Name() const {
\r
1152 /// Set the name of the element.
\r
1153 void SetName( const char* str, bool staticMem=false ) {
\r
1154 SetValue( str, staticMem );
\r
1157 virtual XMLElement* ToElement() {
\r
1160 virtual const XMLElement* ToElement() const {
\r
1163 virtual bool Accept( XMLVisitor* visitor ) const;
\r
1165 /** Given an attribute name, Attribute() returns the value
\r
1166 for the attribute of that name, or null if none
\r
1167 exists. For example:
\r
1170 const char* value = ele->Attribute( "foo" );
\r
1173 The 'value' parameter is normally null. However, if specified,
\r
1174 the attribute will only be returned if the 'name' and 'value'
\r
1175 match. This allow you to write code:
\r
1178 if ( ele->Attribute( "foo", "bar" ) ) callFooIsBar();
\r
1183 if ( ele->Attribute( "foo" ) ) {
\r
1184 if ( strcmp( ele->Attribute( "foo" ), "bar" ) == 0 ) callFooIsBar();
\r
1188 const char* Attribute( const char* name, const char* value=0 ) const;
\r
1190 /** Given an attribute name, IntAttribute() returns the value
\r
1191 of the attribute interpreted as an integer. 0 will be
\r
1192 returned if there is an error. For a method with error
\r
1193 checking, see QueryIntAttribute()
\r
1195 int IntAttribute( const char* name ) const {
\r
1197 QueryIntAttribute( name, &i );
\r
1200 /// See IntAttribute()
\r
1201 unsigned UnsignedAttribute( const char* name ) const {
\r
1203 QueryUnsignedAttribute( name, &i );
\r
1206 /// See IntAttribute()
\r
1207 bool BoolAttribute( const char* name ) const {
\r
1209 QueryBoolAttribute( name, &b );
\r
1212 /// See IntAttribute()
\r
1213 double DoubleAttribute( const char* name ) const {
\r
1215 QueryDoubleAttribute( name, &d );
\r
1218 /// See IntAttribute()
\r
1219 float FloatAttribute( const char* name ) const {
\r
1221 QueryFloatAttribute( name, &f );
\r
1225 /** Given an attribute name, QueryIntAttribute() returns
\r
1226 XML_NO_ERROR, XML_WRONG_ATTRIBUTE_TYPE if the conversion
\r
1227 can't be performed, or XML_NO_ATTRIBUTE if the attribute
\r
1228 doesn't exist. If successful, the result of the conversion
\r
1229 will be written to 'value'. If not successful, nothing will
\r
1230 be written to 'value'. This allows you to provide default
\r
1235 QueryIntAttribute( "foo", &value ); // if "foo" isn't found, value will still be 10
\r
1238 XMLError QueryIntAttribute( const char* name, int* value ) const {
\r
1239 const XMLAttribute* a = FindAttribute( name );
\r
1241 return XML_NO_ATTRIBUTE;
\r
1243 return a->QueryIntValue( value );
\r
1245 /// See QueryIntAttribute()
\r
1246 XMLError QueryUnsignedAttribute( const char* name, unsigned int* value ) const {
\r
1247 const XMLAttribute* a = FindAttribute( name );
\r
1249 return XML_NO_ATTRIBUTE;
\r
1251 return a->QueryUnsignedValue( value );
\r
1253 /// See QueryIntAttribute()
\r
1254 XMLError QueryBoolAttribute( const char* name, bool* value ) const {
\r
1255 const XMLAttribute* a = FindAttribute( name );
\r
1257 return XML_NO_ATTRIBUTE;
\r
1259 return a->QueryBoolValue( value );
\r
1261 /// See QueryIntAttribute()
\r
1262 XMLError QueryDoubleAttribute( const char* name, double* value ) const {
\r
1263 const XMLAttribute* a = FindAttribute( name );
\r
1265 return XML_NO_ATTRIBUTE;
\r
1267 return a->QueryDoubleValue( value );
\r
1269 /// See QueryIntAttribute()
\r
1270 XMLError QueryFloatAttribute( const char* name, float* value ) const {
\r
1271 const XMLAttribute* a = FindAttribute( name );
\r
1273 return XML_NO_ATTRIBUTE;
\r
1275 return a->QueryFloatValue( value );
\r
1279 /** Given an attribute name, QueryAttribute() returns
\r
1280 XML_NO_ERROR, XML_WRONG_ATTRIBUTE_TYPE if the conversion
\r
1281 can't be performed, or XML_NO_ATTRIBUTE if the attribute
\r
1282 doesn't exist. It is overloaded for the primitive types,
\r
1283 and is a generally more convenient replacement of
\r
1284 QueryIntAttribute() and related functions.
\r
1286 If successful, the result of the conversion
\r
1287 will be written to 'value'. If not successful, nothing will
\r
1288 be written to 'value'. This allows you to provide default
\r
1293 QueryAttribute( "foo", &value ); // if "foo" isn't found, value will still be 10
\r
1296 int QueryAttribute( const char* name, int* value ) const {
\r
1297 return QueryIntAttribute( name, value );
\r
1300 int QueryAttribute( const char* name, unsigned int* value ) const {
\r
1301 return QueryUnsignedAttribute( name, value );
\r
1304 int QueryAttribute( const char* name, bool* value ) const {
\r
1305 return QueryBoolAttribute( name, value );
\r
1308 int QueryAttribute( const char* name, double* value ) const {
\r
1309 return QueryDoubleAttribute( name, value );
\r
1312 int QueryAttribute( const char* name, float* value ) const {
\r
1313 return QueryFloatAttribute( name, value );
\r
1316 /// Sets the named attribute to value.
\r
1317 void SetAttribute( const char* name, const char* value ) {
\r
1318 XMLAttribute* a = FindOrCreateAttribute( name );
\r
1319 a->SetAttribute( value );
\r
1321 /// Sets the named attribute to value.
\r
1322 void SetAttribute( const char* name, int value ) {
\r
1323 XMLAttribute* a = FindOrCreateAttribute( name );
\r
1324 a->SetAttribute( value );
\r
1326 /// Sets the named attribute to value.
\r
1327 void SetAttribute( const char* name, unsigned value ) {
\r
1328 XMLAttribute* a = FindOrCreateAttribute( name );
\r
1329 a->SetAttribute( value );
\r
1331 /// Sets the named attribute to value.
\r
1332 void SetAttribute( const char* name, bool value ) {
\r
1333 XMLAttribute* a = FindOrCreateAttribute( name );
\r
1334 a->SetAttribute( value );
\r
1336 /// Sets the named attribute to value.
\r
1337 void SetAttribute( const char* name, double value ) {
\r
1338 XMLAttribute* a = FindOrCreateAttribute( name );
\r
1339 a->SetAttribute( value );
\r
1341 /// Sets the named attribute to value.
\r
1342 void SetAttribute( const char* name, float value ) {
\r
1343 XMLAttribute* a = FindOrCreateAttribute( name );
\r
1344 a->SetAttribute( value );
\r
1348 Delete an attribute.
\r
1350 void DeleteAttribute( const char* name );
\r
1352 /// Return the first attribute in the list.
\r
1353 const XMLAttribute* FirstAttribute() const {
\r
1354 return _rootAttribute;
\r
1356 /// Query a specific attribute in the list.
\r
1357 const XMLAttribute* FindAttribute( const char* name ) const;
\r
1359 /** Convenience function for easy access to the text inside an element. Although easy
\r
1360 and concise, GetText() is limited compared to getting the XMLText child
\r
1361 and accessing it directly.
\r
1363 If the first child of 'this' is a XMLText, the GetText()
\r
1364 returns the character string of the Text node, else null is returned.
\r
1366 This is a convenient method for getting the text of simple contained text:
\r
1368 <foo>This is text</foo>
\r
1369 const char* str = fooElement->GetText();
\r
1372 'str' will be a pointer to "This is text".
\r
1374 Note that this function can be misleading. If the element foo was created from
\r
1377 <foo><b>This is text</b></foo>
\r
1380 then the value of str would be null. The first child node isn't a text node, it is
\r
1381 another element. From this XML:
\r
1383 <foo>This is <b>text</b></foo>
\r
1385 GetText() will return "This is ".
\r
1387 const char* GetText() const;
\r
1389 /** Convenience function for easy access to the text inside an element. Although easy
\r
1390 and concise, SetText() is limited compared to creating an XMLText child
\r
1391 and mutating it directly.
\r
1393 If the first child of 'this' is a XMLText, SetText() sets its value to
\r
1394 the given string, otherwise it will create a first child that is an XMLText.
\r
1396 This is a convenient method for setting the text of simple contained text:
\r
1398 <foo>This is text</foo>
\r
1399 fooElement->SetText( "Hullaballoo!" );
\r
1400 <foo>Hullaballoo!</foo>
\r
1403 Note that this function can be misleading. If the element foo was created from
\r
1406 <foo><b>This is text</b></foo>
\r
1409 then it will not change "This is text", but rather prefix it with a text element:
\r
1411 <foo>Hullaballoo!<b>This is text</b></foo>
\r
1418 SetText() will generate
\r
1420 <foo>Hullaballoo!</foo>
\r
1423 void SetText( const char* inText );
\r
1424 /// Convenience method for setting text inside an element. See SetText() for important limitations.
\r
1425 void SetText( int value );
\r
1426 /// Convenience method for setting text inside an element. See SetText() for important limitations.
\r
1427 void SetText( unsigned value );
\r
1428 /// Convenience method for setting text inside an element. See SetText() for important limitations.
\r
1429 void SetText( bool value );
\r
1430 /// Convenience method for setting text inside an element. See SetText() for important limitations.
\r
1431 void SetText( double value );
\r
1432 /// Convenience method for setting text inside an element. See SetText() for important limitations.
\r
1433 void SetText( float value );
\r
1436 Convenience method to query the value of a child text node. This is probably best
\r
1437 shown by example. Given you have a document is this form:
\r
1445 The QueryIntText() and similar functions provide a safe and easier way to get to the
\r
1446 "value" of x and y.
\r
1450 float y = 0; // types of x and y are contrived for example
\r
1451 const XMLElement* xElement = pointElement->FirstChildElement( "x" );
\r
1452 const XMLElement* yElement = pointElement->FirstChildElement( "y" );
\r
1453 xElement->QueryIntText( &x );
\r
1454 yElement->QueryFloatText( &y );
\r
1457 @returns XML_SUCCESS (0) on success, XML_CAN_NOT_CONVERT_TEXT if the text cannot be converted
\r
1458 to the requested type, and XML_NO_TEXT_NODE if there is no child text to query.
\r
1461 XMLError QueryIntText( int* ival ) const;
\r
1462 /// See QueryIntText()
\r
1463 XMLError QueryUnsignedText( unsigned* uval ) const;
\r
1464 /// See QueryIntText()
\r
1465 XMLError QueryBoolText( bool* bval ) const;
\r
1466 /// See QueryIntText()
\r
1467 XMLError QueryDoubleText( double* dval ) const;
\r
1468 /// See QueryIntText()
\r
1469 XMLError QueryFloatText( float* fval ) const;
\r
1477 int ClosingType() const {
\r
1478 return _closingType;
\r
1480 virtual XMLNode* ShallowClone( XMLDocument* document ) const;
\r
1481 virtual bool ShallowEqual( const XMLNode* compare ) const;
\r
1484 char* ParseDeep( char* p, StrPair* endTag );
\r
1487 XMLElement( XMLDocument* doc );
\r
1488 virtual ~XMLElement();
\r
1489 XMLElement( const XMLElement& ); // not supported
\r
1490 void operator=( const XMLElement& ); // not supported
\r
1492 XMLAttribute* FindAttribute( const char* name ) {
\r
1493 return const_cast<XMLAttribute*>(const_cast<const XMLElement*>(this)->FindAttribute( name ));
\r
1495 XMLAttribute* FindOrCreateAttribute( const char* name );
\r
1496 //void LinkAttribute( XMLAttribute* attrib );
\r
1497 char* ParseAttributes( char* p );
\r
1498 static void DeleteAttribute( XMLAttribute* attribute );
\r
1500 enum { BUF_SIZE = 200 };
\r
1502 // The attribute list is ordered; there is no 'lastAttribute'
\r
1503 // because the list needs to be scanned for dupes before adding
\r
1504 // a new attribute.
\r
1505 XMLAttribute* _rootAttribute;
\r
1510 PRESERVE_WHITESPACE,
\r
1511 COLLAPSE_WHITESPACE
\r
1515 /** A Document binds together all the functionality.
\r
1516 It can be saved, loaded, and printed to the screen.
\r
1517 All Nodes are connected and allocated to a Document.
\r
1518 If the Document is deleted, all its Nodes are also deleted.
\r
1520 class TINYXML2_LIB XMLDocument : public XMLNode
\r
1522 friend class XMLElement;
\r
1525 XMLDocument( bool processEntities = true, Whitespace = PRESERVE_WHITESPACE );
\r
1528 virtual XMLDocument* ToDocument() {
\r
1529 TIXMLASSERT( this == _document );
\r
1532 virtual const XMLDocument* ToDocument() const {
\r
1533 TIXMLASSERT( this == _document );
\r
1538 Parse an XML file from a character string.
\r
1539 Returns XML_NO_ERROR (0) on success, or
\r
1542 You may optionally pass in the 'nBytes', which is
\r
1543 the number of bytes which will be parsed. If not
\r
1544 specified, TinyXML-2 will assume 'xml' points to a
\r
1545 null terminated string.
\r
1547 XMLError Parse( const char* xml, size_t nBytes=(size_t)(-1) );
\r
1550 Load an XML file from disk.
\r
1551 Returns XML_NO_ERROR (0) on success, or
\r
1554 XMLError LoadFile( const char* filename );
\r
1557 Load an XML file from disk. You are responsible
\r
1558 for providing and closing the FILE*.
\r
1560 NOTE: The file should be opened as binary ("rb")
\r
1561 not text in order for TinyXML-2 to correctly
\r
1562 do newline normalization.
\r
1564 Returns XML_NO_ERROR (0) on success, or
\r
1567 XMLError LoadFile( FILE* );
\r
1570 Save the XML file to disk.
\r
1571 Returns XML_NO_ERROR (0) on success, or
\r
1574 XMLError SaveFile( const char* filename, bool compact = false );
\r
1577 Save the XML file to disk. You are responsible
\r
1578 for providing and closing the FILE*.
\r
1580 Returns XML_NO_ERROR (0) on success, or
\r
1583 XMLError SaveFile( FILE* fp, bool compact = false );
\r
1585 bool ProcessEntities() const {
\r
1586 return _processEntities;
\r
1588 Whitespace WhitespaceMode() const {
\r
1589 return _whitespace;
\r
1593 Returns true if this document has a leading Byte Order Mark of UTF8.
\r
1595 bool HasBOM() const {
\r
1598 /** Sets whether to write the BOM when writing the file.
\r
1600 void SetBOM( bool useBOM ) {
\r
1601 _writeBOM = useBOM;
\r
1604 /** Return the root element of DOM. Equivalent to FirstChildElement().
\r
1605 To get the first node, use FirstChild().
\r
1607 XMLElement* RootElement() {
\r
1608 return FirstChildElement();
\r
1610 const XMLElement* RootElement() const {
\r
1611 return FirstChildElement();
\r
1614 /** Print the Document. If the Printer is not provided, it will
\r
1615 print to stdout. If you provide Printer, this can print to a file:
\r
1617 XMLPrinter printer( fp );
\r
1618 doc.Print( &printer );
\r
1621 Or you can use a printer to print to memory:
\r
1623 XMLPrinter printer;
\r
1624 doc.Print( &printer );
\r
1625 // printer.CStr() has a const char* to the XML
\r
1628 void Print( XMLPrinter* streamer=0 ) const;
\r
1629 virtual bool Accept( XMLVisitor* visitor ) const;
\r
1632 Create a new Element associated with
\r
1633 this Document. The memory for the Element
\r
1634 is managed by the Document.
\r
1636 XMLElement* NewElement( const char* name );
\r
1638 Create a new Comment associated with
\r
1639 this Document. The memory for the Comment
\r
1640 is managed by the Document.
\r
1642 XMLComment* NewComment( const char* comment );
\r
1644 Create a new Text associated with
\r
1645 this Document. The memory for the Text
\r
1646 is managed by the Document.
\r
1648 XMLText* NewText( const char* text );
\r
1650 Create a new Declaration associated with
\r
1651 this Document. The memory for the object
\r
1652 is managed by the Document.
\r
1654 If the 'text' param is null, the standard
\r
1655 declaration is used.:
\r
1657 <?xml version="1.0" encoding="UTF-8"?>
\r
1660 XMLDeclaration* NewDeclaration( const char* text=0 );
\r
1662 Create a new Unknown associated with
\r
1663 this Document. The memory for the object
\r
1664 is managed by the Document.
\r
1666 XMLUnknown* NewUnknown( const char* text );
\r
1669 Delete a node associated with this document.
\r
1670 It will be unlinked from the DOM.
\r
1672 void DeleteNode( XMLNode* node );
\r
1674 void SetError( XMLError error, const char* str1, const char* str2 );
\r
1676 /// Return true if there was an error parsing the document.
\r
1677 bool Error() const {
\r
1678 return _errorID != XML_NO_ERROR;
\r
1680 /// Return the errorID.
\r
1681 XMLError ErrorID() const {
\r
1684 const char* ErrorName() const;
\r
1686 /// Return a possibly helpful diagnostic location or string.
\r
1687 const char* GetErrorStr1() const {
\r
1688 return _errorStr1;
\r
1690 /// Return a possibly helpful secondary diagnostic location or string.
\r
1691 const char* GetErrorStr2() const {
\r
1692 return _errorStr2;
\r
1694 /// If there is an error, print it to stdout.
\r
1695 void PrintError() const;
\r
1697 /// Clear the document, resetting it to the initial state.
\r
1701 char* Identify( char* p, XMLNode** node );
\r
1703 virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const {
\r
1706 virtual bool ShallowEqual( const XMLNode* /*compare*/ ) const {
\r
1711 XMLDocument( const XMLDocument& ); // not supported
\r
1712 void operator=( const XMLDocument& ); // not supported
\r
1715 bool _processEntities;
\r
1716 XMLError _errorID;
\r
1717 Whitespace _whitespace;
\r
1718 const char* _errorStr1;
\r
1719 const char* _errorStr2;
\r
1720 char* _charBuffer;
\r
1722 MemPoolT< sizeof(XMLElement) > _elementPool;
\r
1723 MemPoolT< sizeof(XMLAttribute) > _attributePool;
\r
1724 MemPoolT< sizeof(XMLText) > _textPool;
\r
1725 MemPoolT< sizeof(XMLComment) > _commentPool;
\r
1727 static const char* _errorNames[XML_ERROR_COUNT];
\r
1734 A XMLHandle is a class that wraps a node pointer with null checks; this is
\r
1735 an incredibly useful thing. Note that XMLHandle is not part of the TinyXML-2
\r
1736 DOM structure. It is a separate utility class.
\r
1741 <Element attributeA = "valueA">
\r
1742 <Child attributeB = "value1" />
\r
1743 <Child attributeB = "value2" />
\r
1748 Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very
\r
1749 easy to write a *lot* of code that looks like:
\r
1752 XMLElement* root = document.FirstChildElement( "Document" );
\r
1755 XMLElement* element = root->FirstChildElement( "Element" );
\r
1758 XMLElement* child = element->FirstChildElement( "Child" );
\r
1761 XMLElement* child2 = child->NextSiblingElement( "Child" );
\r
1764 // Finally do something useful.
\r
1767 And that doesn't even cover "else" cases. XMLHandle addresses the verbosity
\r
1768 of such code. A XMLHandle checks for null pointers so it is perfectly safe
\r
1769 and correct to use:
\r
1772 XMLHandle docHandle( &document );
\r
1773 XMLElement* child2 = docHandle.FirstChildElement( "Document" ).FirstChildElement( "Element" ).FirstChildElement().NextSiblingElement();
\r
1776 // do something useful
\r
1779 Which is MUCH more concise and useful.
\r
1781 It is also safe to copy handles - internally they are nothing more than node pointers.
\r
1783 XMLHandle handleCopy = handle;
\r
1786 See also XMLConstHandle, which is the same as XMLHandle, but operates on const objects.
\r
1788 class TINYXML2_LIB XMLHandle
\r
1791 /// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
\r
1792 XMLHandle( XMLNode* node ) {
\r
1795 /// Create a handle from a node.
\r
1796 XMLHandle( XMLNode& node ) {
\r
1799 /// Copy constructor
\r
1800 XMLHandle( const XMLHandle& ref ) {
\r
1801 _node = ref._node;
\r
1804 XMLHandle& operator=( const XMLHandle& ref ) {
\r
1805 _node = ref._node;
\r
1809 /// Get the first child of this handle.
\r
1810 XMLHandle FirstChild() {
\r
1811 return XMLHandle( _node ? _node->FirstChild() : 0 );
\r
1813 /// Get the first child element of this handle.
\r
1814 XMLHandle FirstChildElement( const char* name = 0 ) {
\r
1815 return XMLHandle( _node ? _node->FirstChildElement( name ) : 0 );
\r
1817 /// Get the last child of this handle.
\r
1818 XMLHandle LastChild() {
\r
1819 return XMLHandle( _node ? _node->LastChild() : 0 );
\r
1821 /// Get the last child element of this handle.
\r
1822 XMLHandle LastChildElement( const char* name = 0 ) {
\r
1823 return XMLHandle( _node ? _node->LastChildElement( name ) : 0 );
\r
1825 /// Get the previous sibling of this handle.
\r
1826 XMLHandle PreviousSibling() {
\r
1827 return XMLHandle( _node ? _node->PreviousSibling() : 0 );
\r
1829 /// Get the previous sibling element of this handle.
\r
1830 XMLHandle PreviousSiblingElement( const char* name = 0 ) {
\r
1831 return XMLHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
\r
1833 /// Get the next sibling of this handle.
\r
1834 XMLHandle NextSibling() {
\r
1835 return XMLHandle( _node ? _node->NextSibling() : 0 );
\r
1837 /// Get the next sibling element of this handle.
\r
1838 XMLHandle NextSiblingElement( const char* name = 0 ) {
\r
1839 return XMLHandle( _node ? _node->NextSiblingElement( name ) : 0 );
\r
1842 /// Safe cast to XMLNode. This can return null.
\r
1843 XMLNode* ToNode() {
\r
1846 /// Safe cast to XMLElement. This can return null.
\r
1847 XMLElement* ToElement() {
\r
1848 return ( ( _node == 0 ) ? 0 : _node->ToElement() );
\r
1850 /// Safe cast to XMLText. This can return null.
\r
1851 XMLText* ToText() {
\r
1852 return ( ( _node == 0 ) ? 0 : _node->ToText() );
\r
1854 /// Safe cast to XMLUnknown. This can return null.
\r
1855 XMLUnknown* ToUnknown() {
\r
1856 return ( ( _node == 0 ) ? 0 : _node->ToUnknown() );
\r
1858 /// Safe cast to XMLDeclaration. This can return null.
\r
1859 XMLDeclaration* ToDeclaration() {
\r
1860 return ( ( _node == 0 ) ? 0 : _node->ToDeclaration() );
\r
1869 A variant of the XMLHandle class for working with const XMLNodes and Documents. It is the
\r
1870 same in all regards, except for the 'const' qualifiers. See XMLHandle for API.
\r
1872 class TINYXML2_LIB XMLConstHandle
\r
1875 XMLConstHandle( const XMLNode* node ) {
\r
1878 XMLConstHandle( const XMLNode& node ) {
\r
1881 XMLConstHandle( const XMLConstHandle& ref ) {
\r
1882 _node = ref._node;
\r
1885 XMLConstHandle& operator=( const XMLConstHandle& ref ) {
\r
1886 _node = ref._node;
\r
1890 const XMLConstHandle FirstChild() const {
\r
1891 return XMLConstHandle( _node ? _node->FirstChild() : 0 );
\r
1893 const XMLConstHandle FirstChildElement( const char* name = 0 ) const {
\r
1894 return XMLConstHandle( _node ? _node->FirstChildElement( name ) : 0 );
\r
1896 const XMLConstHandle LastChild() const {
\r
1897 return XMLConstHandle( _node ? _node->LastChild() : 0 );
\r
1899 const XMLConstHandle LastChildElement( const char* name = 0 ) const {
\r
1900 return XMLConstHandle( _node ? _node->LastChildElement( name ) : 0 );
\r
1902 const XMLConstHandle PreviousSibling() const {
\r
1903 return XMLConstHandle( _node ? _node->PreviousSibling() : 0 );
\r
1905 const XMLConstHandle PreviousSiblingElement( const char* name = 0 ) const {
\r
1906 return XMLConstHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
\r
1908 const XMLConstHandle NextSibling() const {
\r
1909 return XMLConstHandle( _node ? _node->NextSibling() : 0 );
\r
1911 const XMLConstHandle NextSiblingElement( const char* name = 0 ) const {
\r
1912 return XMLConstHandle( _node ? _node->NextSiblingElement( name ) : 0 );
\r
1916 const XMLNode* ToNode() const {
\r
1919 const XMLElement* ToElement() const {
\r
1920 return ( ( _node == 0 ) ? 0 : _node->ToElement() );
\r
1922 const XMLText* ToText() const {
\r
1923 return ( ( _node == 0 ) ? 0 : _node->ToText() );
\r
1925 const XMLUnknown* ToUnknown() const {
\r
1926 return ( ( _node == 0 ) ? 0 : _node->ToUnknown() );
\r
1928 const XMLDeclaration* ToDeclaration() const {
\r
1929 return ( ( _node == 0 ) ? 0 : _node->ToDeclaration() );
\r
1933 const XMLNode* _node;
\r
1938 Printing functionality. The XMLPrinter gives you more
\r
1939 options than the XMLDocument::Print() method.
\r
1942 -# Print to memory.
\r
1943 -# Print to a file you provide.
\r
1944 -# Print XML without a XMLDocument.
\r
1949 XMLPrinter printer;
\r
1950 doc.Print( &printer );
\r
1951 SomeFunction( printer.CStr() );
\r
1956 You provide the file pointer.
\r
1958 XMLPrinter printer( fp );
\r
1959 doc.Print( &printer );
\r
1962 Print without a XMLDocument
\r
1964 When loading, an XML parser is very useful. However, sometimes
\r
1965 when saving, it just gets in the way. The code is often set up
\r
1966 for streaming, and constructing the DOM is just overhead.
\r
1968 The Printer supports the streaming case. The following code
\r
1969 prints out a trivially simple XML file without ever creating
\r
1973 XMLPrinter printer( fp );
\r
1974 printer.OpenElement( "foo" );
\r
1975 printer.PushAttribute( "foo", "bar" );
\r
1976 printer.CloseElement();
\r
1979 class TINYXML2_LIB XMLPrinter : public XMLVisitor
\r
1982 /** Construct the printer. If the FILE* is specified,
\r
1983 this will print to the FILE. Else it will print
\r
1984 to memory, and the result is available in CStr().
\r
1985 If 'compact' is set to true, then output is created
\r
1986 with only required whitespace and newlines.
\r
1988 XMLPrinter( FILE* file=0, bool compact = false, int depth = 0 );
\r
1989 virtual ~XMLPrinter() {}
\r
1991 /** If streaming, write the BOM and declaration. */
\r
1992 void PushHeader( bool writeBOM, bool writeDeclaration );
\r
1993 /** If streaming, start writing an element.
\r
1994 The element must be closed with CloseElement()
\r
1996 void OpenElement( const char* name, bool compactMode=false );
\r
1997 /// If streaming, add an attribute to an open element.
\r
1998 void PushAttribute( const char* name, const char* value );
\r
1999 void PushAttribute( const char* name, int value );
\r
2000 void PushAttribute( const char* name, unsigned value );
\r
2001 void PushAttribute( const char* name, bool value );
\r
2002 void PushAttribute( const char* name, double value );
\r
2003 /// If streaming, close the Element.
\r
2004 virtual void CloseElement( bool compactMode=false );
\r
2006 /// Add a text node.
\r
2007 void PushText( const char* text, bool cdata=false );
\r
2008 /// Add a text node from an integer.
\r
2009 void PushText( int value );
\r
2010 /// Add a text node from an unsigned.
\r
2011 void PushText( unsigned value );
\r
2012 /// Add a text node from a bool.
\r
2013 void PushText( bool value );
\r
2014 /// Add a text node from a float.
\r
2015 void PushText( float value );
\r
2016 /// Add a text node from a double.
\r
2017 void PushText( double value );
\r
2020 void PushComment( const char* comment );
\r
2022 void PushDeclaration( const char* value );
\r
2023 void PushUnknown( const char* value );
\r
2025 virtual bool VisitEnter( const XMLDocument& /*doc*/ );
\r
2026 virtual bool VisitExit( const XMLDocument& /*doc*/ ) {
\r
2030 virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute );
\r
2031 virtual bool VisitExit( const XMLElement& element );
\r
2033 virtual bool Visit( const XMLText& text );
\r
2034 virtual bool Visit( const XMLComment& comment );
\r
2035 virtual bool Visit( const XMLDeclaration& declaration );
\r
2036 virtual bool Visit( const XMLUnknown& unknown );
\r
2039 If in print to memory mode, return a pointer to
\r
2040 the XML file in memory.
\r
2042 const char* CStr() const {
\r
2043 return _buffer.Mem();
\r
2046 If in print to memory mode, return the size
\r
2047 of the XML file in memory. (Note the size returned
\r
2048 includes the terminating null.)
\r
2050 int CStrSize() const {
\r
2051 return _buffer.Size();
\r
2054 If in print to memory mode, reset the buffer to the
\r
2057 void ClearBuffer() {
\r
2063 virtual bool CompactMode( const XMLElement& ) { return _compactMode; }
\r
2065 /** Prints out the space before an element. You may override to change
\r
2066 the space and tabs used. A PrintSpace() override should call Print().
\r
2068 virtual void PrintSpace( int depth );
\r
2069 void Print( const char* format, ... );
\r
2071 void SealElementIfJustOpened();
\r
2072 bool _elementJustOpened;
\r
2073 DynArray< const char*, 10 > _stack;
\r
2076 void PrintString( const char*, bool restrictedEntitySet ); // prints out, after detecting entities.
\r
2078 bool _firstElement;
\r
2082 bool _processEntities;
\r
2083 bool _compactMode;
\r
2086 ENTITY_RANGE = 64,
\r
2089 bool _entityFlag[ENTITY_RANGE];
\r
2090 bool _restrictedEntityFlag[ENTITY_RANGE];
\r
2092 DynArray< char, 20 > _buffer;
\r
2098 #if defined(_MSC_VER)
\r
2099 # pragma warning(pop)
\r
2102 #endif // TINYXML2_INCLUDED
\r