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
99 #include <tinyxml/cpPlugins_tinyxml2_Export.h>
\r
100 #undef TINYXML2_LIB
\r
101 #define TINYXML2_LIB cpPlugins_tinyxml2_EXPORT
\r
107 class XMLAttribute;
\r
110 class XMLDeclaration;
\r
115 A class that wraps strings. Normally stores the start and end
\r
116 pointers into the XML file itself, and will apply normalization
\r
117 and entity translation if actually read. Can also store (and memory
\r
118 manage) a traditional char[]
\r
124 NEEDS_ENTITY_PROCESSING = 0x01,
\r
125 NEEDS_NEWLINE_NORMALIZATION = 0x02,
\r
126 NEEDS_WHITESPACE_COLLAPSING = 0x04,
\r
128 TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
\r
129 TEXT_ELEMENT_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
\r
130 ATTRIBUTE_NAME = 0,
\r
131 ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
\r
132 ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
\r
133 COMMENT = NEEDS_NEWLINE_NORMALIZATION
\r
136 StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {}
\r
139 void Set( char* start, char* end, int flags ) {
\r
143 _flags = flags | NEEDS_FLUSH;
\r
146 const char* GetStr();
\r
148 bool Empty() const {
\r
149 return _start == _end;
\r
152 void SetInternedStr( const char* str ) {
\r
154 _start = const_cast<char*>(str);
\r
157 void SetStr( const char* str, int flags=0 );
\r
159 char* ParseText( char* in, const char* endTag, int strFlags );
\r
160 char* ParseName( char* in );
\r
162 void TransferTo( StrPair* other );
\r
166 void CollapseWhitespace();
\r
169 NEEDS_FLUSH = 0x100,
\r
170 NEEDS_DELETE = 0x200
\r
177 StrPair( const StrPair& other ); // not supported
\r
178 void operator=( StrPair& other ); // not supported, use TransferTo()
\r
183 A dynamic array of Plain Old Data. Doesn't support constructors, etc.
\r
184 Has a small initial memory pool, so that low or no usage will not
\r
185 cause a call to new/delete
\r
187 template <class T, int INITIAL_SIZE>
\r
193 _allocated = INITIAL_SIZE;
\r
198 if ( _mem != _pool ) {
\r
208 TIXMLASSERT( _size < INT_MAX );
\r
209 EnsureCapacity( _size+1 );
\r
213 T* PushArr( int count ) {
\r
214 TIXMLASSERT( count >= 0 );
\r
215 TIXMLASSERT( _size <= INT_MAX - count );
\r
216 EnsureCapacity( _size+count );
\r
217 T* ret = &_mem[_size];
\r
223 TIXMLASSERT( _size > 0 );
\r
224 return _mem[--_size];
\r
227 void PopArr( int count ) {
\r
228 TIXMLASSERT( _size >= count );
\r
232 bool Empty() const {
\r
236 T& operator[](int i) {
\r
237 TIXMLASSERT( i>= 0 && i < _size );
\r
241 const T& operator[](int i) const {
\r
242 TIXMLASSERT( i>= 0 && i < _size );
\r
246 const T& PeekTop() const {
\r
247 TIXMLASSERT( _size > 0 );
\r
248 return _mem[ _size - 1];
\r
252 TIXMLASSERT( _size >= 0 );
\r
256 int Capacity() const {
\r
257 TIXMLASSERT( _allocated >= INITIAL_SIZE );
\r
261 const T* Mem() const {
\r
262 TIXMLASSERT( _mem );
\r
267 TIXMLASSERT( _mem );
\r
272 DynArray( const DynArray& ); // not supported
\r
273 void operator=( const DynArray& ); // not supported
\r
275 void EnsureCapacity( int cap ) {
\r
276 TIXMLASSERT( cap > 0 );
\r
277 if ( cap > _allocated ) {
\r
278 TIXMLASSERT( cap <= INT_MAX / 2 );
\r
279 int newAllocated = cap * 2;
\r
280 T* newMem = new T[newAllocated];
\r
281 memcpy( newMem, _mem, sizeof(T)*_size ); // warning: not using constructors, only works for PODs
\r
282 if ( _mem != _pool ) {
\r
286 _allocated = newAllocated;
\r
291 T _pool[INITIAL_SIZE];
\r
292 int _allocated; // objects allocated
\r
293 int _size; // number objects in use
\r
298 Parent virtual class of a pool for fast allocation
\r
299 and deallocation of objects.
\r
305 virtual ~MemPool() {}
\r
307 virtual int ItemSize() const = 0;
\r
308 virtual void* Alloc() = 0;
\r
309 virtual void Free( void* ) = 0;
\r
310 virtual void SetTracked() = 0;
\r
311 virtual void Clear() = 0;
\r
316 Template child class to create pools of the correct type.
\r
318 template< int SIZE >
\r
319 class MemPoolT : public MemPool
\r
322 MemPoolT() : _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {}
\r
328 // Delete the blocks.
\r
329 while( !_blockPtrs.Empty()) {
\r
330 Block* b = _blockPtrs.Pop();
\r
334 _currentAllocs = 0;
\r
340 virtual int ItemSize() const {
\r
343 int CurrentAllocs() const {
\r
344 return _currentAllocs;
\r
347 virtual void* Alloc() {
\r
349 // Need a new block.
\r
350 Block* block = new Block();
\r
351 _blockPtrs.Push( block );
\r
353 for( int i=0; i<COUNT-1; ++i ) {
\r
354 block->chunk[i].next = &block->chunk[i+1];
\r
356 block->chunk[COUNT-1].next = 0;
\r
357 _root = block->chunk;
\r
359 void* result = _root;
\r
360 _root = _root->next;
\r
363 if ( _currentAllocs > _maxAllocs ) {
\r
364 _maxAllocs = _currentAllocs;
\r
371 virtual void Free( void* mem ) {
\r
376 Chunk* chunk = static_cast<Chunk*>( mem );
\r
378 memset( chunk, 0xfe, sizeof(Chunk) );
\r
380 chunk->next = _root;
\r
383 void Trace( const char* name ) {
\r
384 printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n",
\r
385 name, _maxAllocs, _maxAllocs*SIZE/1024, _currentAllocs, SIZE, _nAllocs, _blockPtrs.Size() );
\r
388 void SetTracked() {
\r
392 int Untracked() const {
\r
393 return _nUntracked;
\r
396 // This number is perf sensitive. 4k seems like a good tradeoff on my machine.
\r
397 // The test file is large, 170k.
\r
398 // Release: VS2010 gcc(no opt)
\r
405 enum { COUNT = (4*1024)/SIZE }; // Some compilers do not accept to use COUNT in private part if COUNT is private
\r
408 MemPoolT( const MemPoolT& ); // not supported
\r
409 void operator=( const MemPoolT& ); // not supported
\r
416 Chunk chunk[COUNT];
\r
418 DynArray< Block*, 10 > _blockPtrs;
\r
421 int _currentAllocs;
\r
430 Implements the interface to the "Visitor pattern" (see the Accept() method.)
\r
431 If you call the Accept() method, it requires being passed a XMLVisitor
\r
432 class to handle callbacks. For nodes that contain other nodes (Document, Element)
\r
433 you will get called with a VisitEnter/VisitExit pair. Nodes that are always leafs
\r
434 are simply called with Visit().
\r
436 If you return 'true' from a Visit method, recursive parsing will continue. If you return
\r
437 false, <b>no children of this node or its siblings</b> will be visited.
\r
439 All flavors of Visit methods have a default implementation that returns 'true' (continue
\r
440 visiting). You need to only override methods that are interesting to you.
\r
442 Generally Accept() is called on the XMLDocument, although all nodes support visiting.
\r
444 You should never change the document from a callback.
\r
446 @sa XMLNode::Accept()
\r
448 class TINYXML2_LIB XMLVisitor
\r
451 virtual ~XMLVisitor() {}
\r
453 /// Visit a document.
\r
454 virtual bool VisitEnter( const XMLDocument& /*doc*/ ) {
\r
457 /// Visit a document.
\r
458 virtual bool VisitExit( const XMLDocument& /*doc*/ ) {
\r
462 /// Visit an element.
\r
463 virtual bool VisitEnter( const XMLElement& /*element*/, const XMLAttribute* /*firstAttribute*/ ) {
\r
466 /// Visit an element.
\r
467 virtual bool VisitExit( const XMLElement& /*element*/ ) {
\r
471 /// Visit a declaration.
\r
472 virtual bool Visit( const XMLDeclaration& /*declaration*/ ) {
\r
475 /// Visit a text node.
\r
476 virtual bool Visit( const XMLText& /*text*/ ) {
\r
479 /// Visit a comment node.
\r
480 virtual bool Visit( const XMLComment& /*comment*/ ) {
\r
483 /// Visit an unknown node.
\r
484 virtual bool Visit( const XMLUnknown& /*unknown*/ ) {
\r
489 // WARNING: must match XMLDocument::_errorNames[]
\r
494 XML_WRONG_ATTRIBUTE_TYPE,
\r
495 XML_ERROR_FILE_NOT_FOUND,
\r
496 XML_ERROR_FILE_COULD_NOT_BE_OPENED,
\r
497 XML_ERROR_FILE_READ_ERROR,
\r
498 XML_ERROR_ELEMENT_MISMATCH,
\r
499 XML_ERROR_PARSING_ELEMENT,
\r
500 XML_ERROR_PARSING_ATTRIBUTE,
\r
501 XML_ERROR_IDENTIFYING_TAG,
\r
502 XML_ERROR_PARSING_TEXT,
\r
503 XML_ERROR_PARSING_CDATA,
\r
504 XML_ERROR_PARSING_COMMENT,
\r
505 XML_ERROR_PARSING_DECLARATION,
\r
506 XML_ERROR_PARSING_UNKNOWN,
\r
507 XML_ERROR_EMPTY_DOCUMENT,
\r
508 XML_ERROR_MISMATCHED_ELEMENT,
\r
510 XML_CAN_NOT_CONVERT_TEXT,
\r
518 Utility functionality.
\r
523 static const char* SkipWhiteSpace( const char* p ) {
\r
525 while( IsWhiteSpace(*p) ) {
\r
531 static char* SkipWhiteSpace( char* p ) {
\r
532 return const_cast<char*>( SkipWhiteSpace( const_cast<const char*>(p) ) );
\r
535 // Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't
\r
536 // correct, but simple, and usually works.
\r
537 static bool IsWhiteSpace( char p ) {
\r
538 return !IsUTF8Continuation(p) && isspace( static_cast<unsigned char>(p) );
\r
541 inline static bool IsNameStartChar( unsigned char ch ) {
\r
543 // This is a heuristic guess in attempt to not implement Unicode-aware isalpha()
\r
546 if ( isalpha( ch ) ) {
\r
549 return ch == ':' || ch == '_';
\r
552 inline static bool IsNameChar( unsigned char ch ) {
\r
553 return IsNameStartChar( ch )
\r
559 inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX ) {
\r
563 return strncmp( p, q, nChar ) == 0;
\r
566 inline static bool IsUTF8Continuation( char p ) {
\r
567 return ( p & 0x80 ) != 0;
\r
570 static const char* ReadBOM( const char* p, bool* hasBOM );
\r
571 // p is the starting location,
\r
572 // the UTF-8 value of the entity will be placed in value, and length filled in.
\r
573 static const char* GetCharacterRef( const char* p, char* value, int* length );
\r
574 static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
\r
576 // converts primitive types to strings
\r
577 static void ToStr( int v, char* buffer, int bufferSize );
\r
578 static void ToStr( unsigned v, char* buffer, int bufferSize );
\r
579 static void ToStr( bool v, char* buffer, int bufferSize );
\r
580 static void ToStr( float v, char* buffer, int bufferSize );
\r
581 static void ToStr( double v, char* buffer, int bufferSize );
\r
583 // converts strings to primitive types
\r
584 static bool ToInt( const char* str, int* value );
\r
585 static bool ToUnsigned( const char* str, unsigned* value );
\r
586 static bool ToBool( const char* str, bool* value );
\r
587 static bool ToFloat( const char* str, float* value );
\r
588 static bool ToDouble( const char* str, double* value );
\r
592 /** XMLNode is a base class for every object that is in the
\r
593 XML Document Object Model (DOM), except XMLAttributes.
\r
594 Nodes have siblings, a parent, and children which can
\r
595 be navigated. A node is always in a XMLDocument.
\r
596 The type of a XMLNode can be queried, and it can
\r
597 be cast to its more defined type.
\r
599 A XMLDocument allocates memory for all its Nodes.
\r
600 When the XMLDocument gets deleted, all its Nodes
\r
601 will also be deleted.
\r
604 A Document can contain: Element (container or leaf)
\r
607 Declaration( leaf )
\r
609 An Element can contain: Element (container or leaf)
\r
611 Attributes (not on tree)
\r
617 class TINYXML2_LIB XMLNode
\r
619 friend class XMLDocument;
\r
620 friend class XMLElement;
\r
623 /// Get the XMLDocument that owns this XMLNode.
\r
624 const XMLDocument* GetDocument() const {
\r
625 TIXMLASSERT( _document );
\r
628 /// Get the XMLDocument that owns this XMLNode.
\r
629 XMLDocument* GetDocument() {
\r
630 TIXMLASSERT( _document );
\r
634 /// Safely cast to an Element, or null.
\r
635 virtual XMLElement* ToElement() {
\r
638 /// Safely cast to Text, or null.
\r
639 virtual XMLText* ToText() {
\r
642 /// Safely cast to a Comment, or null.
\r
643 virtual XMLComment* ToComment() {
\r
646 /// Safely cast to a Document, or null.
\r
647 virtual XMLDocument* ToDocument() {
\r
650 /// Safely cast to a Declaration, or null.
\r
651 virtual XMLDeclaration* ToDeclaration() {
\r
654 /// Safely cast to an Unknown, or null.
\r
655 virtual XMLUnknown* ToUnknown() {
\r
659 virtual const XMLElement* ToElement() const {
\r
662 virtual const XMLText* ToText() const {
\r
665 virtual const XMLComment* ToComment() const {
\r
668 virtual const XMLDocument* ToDocument() const {
\r
671 virtual const XMLDeclaration* ToDeclaration() const {
\r
674 virtual const XMLUnknown* ToUnknown() const {
\r
678 /** The meaning of 'value' changes for the specific type.
\r
680 Document: empty (NULL is returned, not an empty string)
\r
681 Element: name of the element
\r
682 Comment: the comment text
\r
683 Unknown: the tag contents
\r
684 Text: the text string
\r
687 const char* Value() const;
\r
689 /** Set the Value of an XML node.
\r
692 void SetValue( const char* val, bool staticMem=false );
\r
694 /// Get the parent of this node on the DOM.
\r
695 const XMLNode* Parent() const {
\r
699 XMLNode* Parent() {
\r
703 /// Returns true if this node has no children.
\r
704 bool NoChildren() const {
\r
705 return !_firstChild;
\r
708 /// Get the first child node, or null if none exists.
\r
709 const XMLNode* FirstChild() const {
\r
710 return _firstChild;
\r
713 XMLNode* FirstChild() {
\r
714 return _firstChild;
\r
717 /** Get the first child element, or optionally the first child
\r
718 element with the specified name.
\r
720 const XMLElement* FirstChildElement( const char* name = 0 ) const;
\r
722 XMLElement* FirstChildElement( const char* name = 0 ) {
\r
723 return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->FirstChildElement( name ));
\r
726 /// Get the last child node, or null if none exists.
\r
727 const XMLNode* LastChild() const {
\r
731 XMLNode* LastChild() {
\r
735 /** Get the last child element or optionally the last child
\r
736 element with the specified name.
\r
738 const XMLElement* LastChildElement( const char* name = 0 ) const;
\r
740 XMLElement* LastChildElement( const char* name = 0 ) {
\r
741 return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->LastChildElement(name) );
\r
744 /// Get the previous (left) sibling node of this node.
\r
745 const XMLNode* PreviousSibling() const {
\r
749 XMLNode* PreviousSibling() {
\r
753 /// Get the previous (left) sibling element of this node, with an optionally supplied name.
\r
754 const XMLElement* PreviousSiblingElement( const char* name = 0 ) const ;
\r
756 XMLElement* PreviousSiblingElement( const char* name = 0 ) {
\r
757 return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->PreviousSiblingElement( name ) );
\r
760 /// Get the next (right) sibling node of this node.
\r
761 const XMLNode* NextSibling() const {
\r
765 XMLNode* NextSibling() {
\r
769 /// Get the next (right) sibling element of this node, with an optionally supplied name.
\r
770 const XMLElement* NextSiblingElement( const char* name = 0 ) const;
\r
772 XMLElement* NextSiblingElement( const char* name = 0 ) {
\r
773 return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->NextSiblingElement( name ) );
\r
777 Add a child node as the last (right) child.
\r
778 If the child node is already part of the document,
\r
779 it is moved from its old location to the new location.
\r
780 Returns the addThis argument or 0 if the node does not
\r
781 belong to the same document.
\r
783 XMLNode* InsertEndChild( XMLNode* addThis );
\r
785 XMLNode* LinkEndChild( XMLNode* addThis ) {
\r
786 return InsertEndChild( addThis );
\r
789 Add a child node as the first (left) child.
\r
790 If the child node is already part of the document,
\r
791 it is moved from its old location to the new location.
\r
792 Returns the addThis argument or 0 if the node does not
\r
793 belong to the same document.
\r
795 XMLNode* InsertFirstChild( XMLNode* addThis );
\r
797 Add a node after the specified child node.
\r
798 If the child node is already part of the document,
\r
799 it is moved from its old location to the new location.
\r
800 Returns the addThis argument or 0 if the afterThis node
\r
801 is not a child of this node, or if the node does not
\r
802 belong to the same document.
\r
804 XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis );
\r
807 Delete all the children of this node.
\r
809 void DeleteChildren();
\r
812 Delete a child of this node.
\r
814 void DeleteChild( XMLNode* node );
\r
817 Make a copy of this node, but not its children.
\r
818 You may pass in a Document pointer that will be
\r
819 the owner of the new Node. If the 'document' is
\r
820 null, then the node returned will be allocated
\r
821 from the current Document. (this->GetDocument())
\r
823 Note: if called on a XMLDocument, this will return null.
\r
825 virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0;
\r
828 Test if 2 nodes are the same, but don't test children.
\r
829 The 2 nodes do not need to be in the same Document.
\r
831 Note: if called on a XMLDocument, this will return false.
\r
833 virtual bool ShallowEqual( const XMLNode* compare ) const = 0;
\r
835 /** Accept a hierarchical visit of the nodes in the TinyXML-2 DOM. Every node in the
\r
836 XML tree will be conditionally visited and the host will be called back
\r
837 via the XMLVisitor interface.
\r
839 This is essentially a SAX interface for TinyXML-2. (Note however it doesn't re-parse
\r
840 the XML for the callbacks, so the performance of TinyXML-2 is unchanged by using this
\r
841 interface versus any other.)
\r
843 The interface has been based on ideas from:
\r
845 - http://www.saxproject.org/
\r
846 - http://c2.com/cgi/wiki?HierarchicalVisitorPattern
\r
848 Which are both good references for "visiting".
\r
850 An example of using Accept():
\r
852 XMLPrinter printer;
\r
853 tinyxmlDoc.Accept( &printer );
\r
854 const char* xmlcstr = printer.CStr();
\r
857 virtual bool Accept( XMLVisitor* visitor ) const = 0;
\r
860 XMLNode( XMLDocument* );
\r
861 virtual ~XMLNode();
\r
863 virtual char* ParseDeep( char*, StrPair* );
\r
865 XMLDocument* _document;
\r
867 mutable StrPair _value;
\r
869 XMLNode* _firstChild;
\r
870 XMLNode* _lastChild;
\r
877 void Unlink( XMLNode* child );
\r
878 static void DeleteNode( XMLNode* node );
\r
879 void InsertChildPreamble( XMLNode* insertThis ) const;
\r
881 XMLNode( const XMLNode& ); // not supported
\r
882 XMLNode& operator=( const XMLNode& ); // not supported
\r
888 Note that a text node can have child element nodes, for example:
\r
890 <root>This is <b>bold</b></root>
\r
893 A text node can have 2 ways to output the next. "normal" output
\r
894 and CDATA. It will default to the mode it was parsed from the XML file and
\r
895 you generally want to leave it alone, but you can change the output mode with
\r
896 SetCData() and query it with CData().
\r
898 class TINYXML2_LIB XMLText : public XMLNode
\r
900 friend class XMLBase;
\r
901 friend class XMLDocument;
\r
903 virtual bool Accept( XMLVisitor* visitor ) const;
\r
905 virtual XMLText* ToText() {
\r
908 virtual const XMLText* ToText() const {
\r
912 /// Declare whether this should be CDATA or standard text.
\r
913 void SetCData( bool isCData ) {
\r
914 _isCData = isCData;
\r
916 /// Returns true if this is a CDATA text element.
\r
917 bool CData() const {
\r
921 virtual XMLNode* ShallowClone( XMLDocument* document ) const;
\r
922 virtual bool ShallowEqual( const XMLNode* compare ) const;
\r
925 XMLText( XMLDocument* doc ) : XMLNode( doc ), _isCData( false ) {}
\r
926 virtual ~XMLText() {}
\r
928 char* ParseDeep( char*, StrPair* endTag );
\r
933 XMLText( const XMLText& ); // not supported
\r
934 XMLText& operator=( const XMLText& ); // not supported
\r
938 /** An XML Comment. */
\r
939 class TINYXML2_LIB XMLComment : public XMLNode
\r
941 friend class XMLDocument;
\r
943 virtual XMLComment* ToComment() {
\r
946 virtual const XMLComment* ToComment() const {
\r
950 virtual bool Accept( XMLVisitor* visitor ) const;
\r
952 virtual XMLNode* ShallowClone( XMLDocument* document ) const;
\r
953 virtual bool ShallowEqual( const XMLNode* compare ) const;
\r
956 XMLComment( XMLDocument* doc );
\r
957 virtual ~XMLComment();
\r
959 char* ParseDeep( char*, StrPair* endTag );
\r
962 XMLComment( const XMLComment& ); // not supported
\r
963 XMLComment& operator=( const XMLComment& ); // not supported
\r
967 /** In correct XML the declaration is the first entry in the file.
\r
969 <?xml version="1.0" standalone="yes"?>
\r
972 TinyXML-2 will happily read or write files without a declaration,
\r
975 The text of the declaration isn't interpreted. It is parsed
\r
976 and written as a string.
\r
978 class TINYXML2_LIB XMLDeclaration : public XMLNode
\r
980 friend class XMLDocument;
\r
982 virtual XMLDeclaration* ToDeclaration() {
\r
985 virtual const XMLDeclaration* ToDeclaration() const {
\r
989 virtual bool Accept( XMLVisitor* visitor ) const;
\r
991 virtual XMLNode* ShallowClone( XMLDocument* document ) const;
\r
992 virtual bool ShallowEqual( const XMLNode* compare ) const;
\r
995 XMLDeclaration( XMLDocument* doc );
\r
996 virtual ~XMLDeclaration();
\r
998 char* ParseDeep( char*, StrPair* endTag );
\r
1001 XMLDeclaration( const XMLDeclaration& ); // not supported
\r
1002 XMLDeclaration& operator=( const XMLDeclaration& ); // not supported
\r
1006 /** Any tag that TinyXML-2 doesn't recognize is saved as an
\r
1007 unknown. It is a tag of text, but should not be modified.
\r
1008 It will be written back to the XML, unchanged, when the file
\r
1011 DTD tags get thrown into XMLUnknowns.
\r
1013 class TINYXML2_LIB XMLUnknown : public XMLNode
\r
1015 friend class XMLDocument;
\r
1017 virtual XMLUnknown* ToUnknown() {
\r
1020 virtual const XMLUnknown* ToUnknown() const {
\r
1024 virtual bool Accept( XMLVisitor* visitor ) const;
\r
1026 virtual XMLNode* ShallowClone( XMLDocument* document ) const;
\r
1027 virtual bool ShallowEqual( const XMLNode* compare ) const;
\r
1030 XMLUnknown( XMLDocument* doc );
\r
1031 virtual ~XMLUnknown();
\r
1033 char* ParseDeep( char*, StrPair* endTag );
\r
1036 XMLUnknown( const XMLUnknown& ); // not supported
\r
1037 XMLUnknown& operator=( const XMLUnknown& ); // not supported
\r
1042 /** An attribute is a name-value pair. Elements have an arbitrary
\r
1043 number of attributes, each with a unique name.
\r
1045 @note The attributes are not XMLNodes. You may only query the
\r
1046 Next() attribute in a list.
\r
1048 class TINYXML2_LIB XMLAttribute
\r
1050 friend class XMLElement;
\r
1052 /// The name of the attribute.
\r
1053 const char* Name() const;
\r
1055 /// The value of the attribute.
\r
1056 const char* Value() const;
\r
1058 /// The next attribute in the list.
\r
1059 const XMLAttribute* Next() const {
\r
1063 /** IntValue interprets the attribute as an integer, and returns the value.
\r
1064 If the value isn't an integer, 0 will be returned. There is no error checking;
\r
1065 use QueryIntValue() if you need error checking.
\r
1067 int IntValue() const {
\r
1069 QueryIntValue( &i );
\r
1072 /// Query as an unsigned integer. See IntValue()
\r
1073 unsigned UnsignedValue() const {
\r
1075 QueryUnsignedValue( &i );
\r
1078 /// Query as a boolean. See IntValue()
\r
1079 bool BoolValue() const {
\r
1081 QueryBoolValue( &b );
\r
1084 /// Query as a double. See IntValue()
\r
1085 double DoubleValue() const {
\r
1087 QueryDoubleValue( &d );
\r
1090 /// Query as a float. See IntValue()
\r
1091 float FloatValue() const {
\r
1093 QueryFloatValue( &f );
\r
1097 /** QueryIntValue interprets the attribute as an integer, and returns the value
\r
1098 in the provided parameter. The function will return XML_NO_ERROR on success,
\r
1099 and XML_WRONG_ATTRIBUTE_TYPE if the conversion is not successful.
\r
1101 XMLError QueryIntValue( int* value ) const;
\r
1102 /// See QueryIntValue
\r
1103 XMLError QueryUnsignedValue( unsigned int* value ) const;
\r
1104 /// See QueryIntValue
\r
1105 XMLError QueryBoolValue( bool* value ) const;
\r
1106 /// See QueryIntValue
\r
1107 XMLError QueryDoubleValue( double* value ) const;
\r
1108 /// See QueryIntValue
\r
1109 XMLError QueryFloatValue( float* value ) const;
\r
1111 /// Set the attribute to a string value.
\r
1112 void SetAttribute( const char* value );
\r
1113 /// Set the attribute to value.
\r
1114 void SetAttribute( int value );
\r
1115 /// Set the attribute to value.
\r
1116 void SetAttribute( unsigned value );
\r
1117 /// Set the attribute to value.
\r
1118 void SetAttribute( bool value );
\r
1119 /// Set the attribute to value.
\r
1120 void SetAttribute( double value );
\r
1121 /// Set the attribute to value.
\r
1122 void SetAttribute( float value );
\r
1125 enum { BUF_SIZE = 200 };
\r
1127 XMLAttribute() : _next( 0 ), _memPool( 0 ) {}
\r
1128 virtual ~XMLAttribute() {}
\r
1130 XMLAttribute( const XMLAttribute& ); // not supported
\r
1131 void operator=( const XMLAttribute& ); // not supported
\r
1132 void SetName( const char* name );
\r
1134 char* ParseDeep( char* p, bool processEntities );
\r
1136 mutable StrPair _name;
\r
1137 mutable StrPair _value;
\r
1138 XMLAttribute* _next;
\r
1139 MemPool* _memPool;
\r
1143 /** The element is a container class. It has a value, the element name,
\r
1144 and can contain other elements, text, comments, and unknowns.
\r
1145 Elements also contain an arbitrary number of attributes.
\r
1147 class TINYXML2_LIB XMLElement : public XMLNode
\r
1149 friend class XMLBase;
\r
1150 friend class XMLDocument;
\r
1152 /// Get the name of an element (which is the Value() of the node.)
\r
1153 const char* Name() const {
\r
1156 /// Set the name of the element.
\r
1157 void SetName( const char* str, bool staticMem=false ) {
\r
1158 SetValue( str, staticMem );
\r
1161 virtual XMLElement* ToElement() {
\r
1164 virtual const XMLElement* ToElement() const {
\r
1167 virtual bool Accept( XMLVisitor* visitor ) const;
\r
1169 /** Given an attribute name, Attribute() returns the value
\r
1170 for the attribute of that name, or null if none
\r
1171 exists. For example:
\r
1174 const char* value = ele->Attribute( "foo" );
\r
1177 The 'value' parameter is normally null. However, if specified,
\r
1178 the attribute will only be returned if the 'name' and 'value'
\r
1179 match. This allow you to write code:
\r
1182 if ( ele->Attribute( "foo", "bar" ) ) callFooIsBar();
\r
1187 if ( ele->Attribute( "foo" ) ) {
\r
1188 if ( strcmp( ele->Attribute( "foo" ), "bar" ) == 0 ) callFooIsBar();
\r
1192 const char* Attribute( const char* name, const char* value=0 ) const;
\r
1194 /** Given an attribute name, IntAttribute() returns the value
\r
1195 of the attribute interpreted as an integer. 0 will be
\r
1196 returned if there is an error. For a method with error
\r
1197 checking, see QueryIntAttribute()
\r
1199 int IntAttribute( const char* name ) const {
\r
1201 QueryIntAttribute( name, &i );
\r
1204 /// See IntAttribute()
\r
1205 unsigned UnsignedAttribute( const char* name ) const {
\r
1207 QueryUnsignedAttribute( name, &i );
\r
1210 /// See IntAttribute()
\r
1211 bool BoolAttribute( const char* name ) const {
\r
1213 QueryBoolAttribute( name, &b );
\r
1216 /// See IntAttribute()
\r
1217 double DoubleAttribute( const char* name ) const {
\r
1219 QueryDoubleAttribute( name, &d );
\r
1222 /// See IntAttribute()
\r
1223 float FloatAttribute( const char* name ) const {
\r
1225 QueryFloatAttribute( name, &f );
\r
1229 /** Given an attribute name, QueryIntAttribute() returns
\r
1230 XML_NO_ERROR, XML_WRONG_ATTRIBUTE_TYPE if the conversion
\r
1231 can't be performed, or XML_NO_ATTRIBUTE if the attribute
\r
1232 doesn't exist. If successful, the result of the conversion
\r
1233 will be written to 'value'. If not successful, nothing will
\r
1234 be written to 'value'. This allows you to provide default
\r
1239 QueryIntAttribute( "foo", &value ); // if "foo" isn't found, value will still be 10
\r
1242 XMLError QueryIntAttribute( const char* name, int* value ) const {
\r
1243 const XMLAttribute* a = FindAttribute( name );
\r
1245 return XML_NO_ATTRIBUTE;
\r
1247 return a->QueryIntValue( value );
\r
1249 /// See QueryIntAttribute()
\r
1250 XMLError QueryUnsignedAttribute( const char* name, unsigned int* value ) const {
\r
1251 const XMLAttribute* a = FindAttribute( name );
\r
1253 return XML_NO_ATTRIBUTE;
\r
1255 return a->QueryUnsignedValue( value );
\r
1257 /// See QueryIntAttribute()
\r
1258 XMLError QueryBoolAttribute( const char* name, bool* value ) const {
\r
1259 const XMLAttribute* a = FindAttribute( name );
\r
1261 return XML_NO_ATTRIBUTE;
\r
1263 return a->QueryBoolValue( value );
\r
1265 /// See QueryIntAttribute()
\r
1266 XMLError QueryDoubleAttribute( const char* name, double* value ) const {
\r
1267 const XMLAttribute* a = FindAttribute( name );
\r
1269 return XML_NO_ATTRIBUTE;
\r
1271 return a->QueryDoubleValue( value );
\r
1273 /// See QueryIntAttribute()
\r
1274 XMLError QueryFloatAttribute( const char* name, float* value ) const {
\r
1275 const XMLAttribute* a = FindAttribute( name );
\r
1277 return XML_NO_ATTRIBUTE;
\r
1279 return a->QueryFloatValue( value );
\r
1283 /** Given an attribute name, QueryAttribute() returns
\r
1284 XML_NO_ERROR, XML_WRONG_ATTRIBUTE_TYPE if the conversion
\r
1285 can't be performed, or XML_NO_ATTRIBUTE if the attribute
\r
1286 doesn't exist. It is overloaded for the primitive types,
\r
1287 and is a generally more convenient replacement of
\r
1288 QueryIntAttribute() and related functions.
\r
1290 If successful, the result of the conversion
\r
1291 will be written to 'value'. If not successful, nothing will
\r
1292 be written to 'value'. This allows you to provide default
\r
1297 QueryAttribute( "foo", &value ); // if "foo" isn't found, value will still be 10
\r
1300 int QueryAttribute( const char* name, int* value ) const {
\r
1301 return QueryIntAttribute( name, value );
\r
1304 int QueryAttribute( const char* name, unsigned int* value ) const {
\r
1305 return QueryUnsignedAttribute( name, value );
\r
1308 int QueryAttribute( const char* name, bool* value ) const {
\r
1309 return QueryBoolAttribute( name, value );
\r
1312 int QueryAttribute( const char* name, double* value ) const {
\r
1313 return QueryDoubleAttribute( name, value );
\r
1316 int QueryAttribute( const char* name, float* value ) const {
\r
1317 return QueryFloatAttribute( name, value );
\r
1320 /// Sets the named attribute to value.
\r
1321 void SetAttribute( const char* name, const char* value ) {
\r
1322 XMLAttribute* a = FindOrCreateAttribute( name );
\r
1323 a->SetAttribute( value );
\r
1325 /// Sets the named attribute to value.
\r
1326 void SetAttribute( const char* name, int value ) {
\r
1327 XMLAttribute* a = FindOrCreateAttribute( name );
\r
1328 a->SetAttribute( value );
\r
1330 /// Sets the named attribute to value.
\r
1331 void SetAttribute( const char* name, unsigned value ) {
\r
1332 XMLAttribute* a = FindOrCreateAttribute( name );
\r
1333 a->SetAttribute( value );
\r
1335 /// Sets the named attribute to value.
\r
1336 void SetAttribute( const char* name, bool value ) {
\r
1337 XMLAttribute* a = FindOrCreateAttribute( name );
\r
1338 a->SetAttribute( value );
\r
1340 /// Sets the named attribute to value.
\r
1341 void SetAttribute( const char* name, double value ) {
\r
1342 XMLAttribute* a = FindOrCreateAttribute( name );
\r
1343 a->SetAttribute( value );
\r
1345 /// Sets the named attribute to value.
\r
1346 void SetAttribute( const char* name, float value ) {
\r
1347 XMLAttribute* a = FindOrCreateAttribute( name );
\r
1348 a->SetAttribute( value );
\r
1352 Delete an attribute.
\r
1354 void DeleteAttribute( const char* name );
\r
1356 /// Return the first attribute in the list.
\r
1357 const XMLAttribute* FirstAttribute() const {
\r
1358 return _rootAttribute;
\r
1360 /// Query a specific attribute in the list.
\r
1361 const XMLAttribute* FindAttribute( const char* name ) const;
\r
1363 /** Convenience function for easy access to the text inside an element. Although easy
\r
1364 and concise, GetText() is limited compared to getting the XMLText child
\r
1365 and accessing it directly.
\r
1367 If the first child of 'this' is a XMLText, the GetText()
\r
1368 returns the character string of the Text node, else null is returned.
\r
1370 This is a convenient method for getting the text of simple contained text:
\r
1372 <foo>This is text</foo>
\r
1373 const char* str = fooElement->GetText();
\r
1376 'str' will be a pointer to "This is text".
\r
1378 Note that this function can be misleading. If the element foo was created from
\r
1381 <foo><b>This is text</b></foo>
\r
1384 then the value of str would be null. The first child node isn't a text node, it is
\r
1385 another element. From this XML:
\r
1387 <foo>This is <b>text</b></foo>
\r
1389 GetText() will return "This is ".
\r
1391 const char* GetText() const;
\r
1393 /** Convenience function for easy access to the text inside an element. Although easy
\r
1394 and concise, SetText() is limited compared to creating an XMLText child
\r
1395 and mutating it directly.
\r
1397 If the first child of 'this' is a XMLText, SetText() sets its value to
\r
1398 the given string, otherwise it will create a first child that is an XMLText.
\r
1400 This is a convenient method for setting the text of simple contained text:
\r
1402 <foo>This is text</foo>
\r
1403 fooElement->SetText( "Hullaballoo!" );
\r
1404 <foo>Hullaballoo!</foo>
\r
1407 Note that this function can be misleading. If the element foo was created from
\r
1410 <foo><b>This is text</b></foo>
\r
1413 then it will not change "This is text", but rather prefix it with a text element:
\r
1415 <foo>Hullaballoo!<b>This is text</b></foo>
\r
1422 SetText() will generate
\r
1424 <foo>Hullaballoo!</foo>
\r
1427 void SetText( const char* inText );
\r
1428 /// Convenience method for setting text inside an element. See SetText() for important limitations.
\r
1429 void SetText( int value );
\r
1430 /// Convenience method for setting text inside an element. See SetText() for important limitations.
\r
1431 void SetText( unsigned value );
\r
1432 /// Convenience method for setting text inside an element. See SetText() for important limitations.
\r
1433 void SetText( bool value );
\r
1434 /// Convenience method for setting text inside an element. See SetText() for important limitations.
\r
1435 void SetText( double value );
\r
1436 /// Convenience method for setting text inside an element. See SetText() for important limitations.
\r
1437 void SetText( float value );
\r
1440 Convenience method to query the value of a child text node. This is probably best
\r
1441 shown by example. Given you have a document is this form:
\r
1449 The QueryIntText() and similar functions provide a safe and easier way to get to the
\r
1450 "value" of x and y.
\r
1454 float y = 0; // types of x and y are contrived for example
\r
1455 const XMLElement* xElement = pointElement->FirstChildElement( "x" );
\r
1456 const XMLElement* yElement = pointElement->FirstChildElement( "y" );
\r
1457 xElement->QueryIntText( &x );
\r
1458 yElement->QueryFloatText( &y );
\r
1461 @returns XML_SUCCESS (0) on success, XML_CAN_NOT_CONVERT_TEXT if the text cannot be converted
\r
1462 to the requested type, and XML_NO_TEXT_NODE if there is no child text to query.
\r
1465 XMLError QueryIntText( int* ival ) const;
\r
1466 /// See QueryIntText()
\r
1467 XMLError QueryUnsignedText( unsigned* uval ) const;
\r
1468 /// See QueryIntText()
\r
1469 XMLError QueryBoolText( bool* bval ) const;
\r
1470 /// See QueryIntText()
\r
1471 XMLError QueryDoubleText( double* dval ) const;
\r
1472 /// See QueryIntText()
\r
1473 XMLError QueryFloatText( float* fval ) const;
\r
1481 int ClosingType() const {
\r
1482 return _closingType;
\r
1484 virtual XMLNode* ShallowClone( XMLDocument* document ) const;
\r
1485 virtual bool ShallowEqual( const XMLNode* compare ) const;
\r
1488 char* ParseDeep( char* p, StrPair* endTag );
\r
1491 XMLElement( XMLDocument* doc );
\r
1492 virtual ~XMLElement();
\r
1493 XMLElement( const XMLElement& ); // not supported
\r
1494 void operator=( const XMLElement& ); // not supported
\r
1496 XMLAttribute* FindAttribute( const char* name ) {
\r
1497 return const_cast<XMLAttribute*>(const_cast<const XMLElement*>(this)->FindAttribute( name ));
\r
1499 XMLAttribute* FindOrCreateAttribute( const char* name );
\r
1500 //void LinkAttribute( XMLAttribute* attrib );
\r
1501 char* ParseAttributes( char* p );
\r
1502 static void DeleteAttribute( XMLAttribute* attribute );
\r
1504 enum { BUF_SIZE = 200 };
\r
1506 // The attribute list is ordered; there is no 'lastAttribute'
\r
1507 // because the list needs to be scanned for dupes before adding
\r
1508 // a new attribute.
\r
1509 XMLAttribute* _rootAttribute;
\r
1514 PRESERVE_WHITESPACE,
\r
1515 COLLAPSE_WHITESPACE
\r
1519 /** A Document binds together all the functionality.
\r
1520 It can be saved, loaded, and printed to the screen.
\r
1521 All Nodes are connected and allocated to a Document.
\r
1522 If the Document is deleted, all its Nodes are also deleted.
\r
1524 class TINYXML2_LIB XMLDocument : public XMLNode
\r
1526 friend class XMLElement;
\r
1529 XMLDocument( bool processEntities = true, Whitespace = PRESERVE_WHITESPACE );
\r
1532 virtual XMLDocument* ToDocument() {
\r
1533 TIXMLASSERT( this == _document );
\r
1536 virtual const XMLDocument* ToDocument() const {
\r
1537 TIXMLASSERT( this == _document );
\r
1542 Parse an XML file from a character string.
\r
1543 Returns XML_NO_ERROR (0) on success, or
\r
1546 You may optionally pass in the 'nBytes', which is
\r
1547 the number of bytes which will be parsed. If not
\r
1548 specified, TinyXML-2 will assume 'xml' points to a
\r
1549 null terminated string.
\r
1551 XMLError Parse( const char* xml, size_t nBytes=(size_t)(-1) );
\r
1554 Load an XML file from disk.
\r
1555 Returns XML_NO_ERROR (0) on success, or
\r
1558 XMLError LoadFile( const char* filename );
\r
1561 Load an XML file from disk. You are responsible
\r
1562 for providing and closing the FILE*.
\r
1564 NOTE: The file should be opened as binary ("rb")
\r
1565 not text in order for TinyXML-2 to correctly
\r
1566 do newline normalization.
\r
1568 Returns XML_NO_ERROR (0) on success, or
\r
1571 XMLError LoadFile( FILE* );
\r
1574 Save the XML file to disk.
\r
1575 Returns XML_NO_ERROR (0) on success, or
\r
1578 XMLError SaveFile( const char* filename, bool compact = false );
\r
1581 Save the XML file to disk. You are responsible
\r
1582 for providing and closing the FILE*.
\r
1584 Returns XML_NO_ERROR (0) on success, or
\r
1587 XMLError SaveFile( FILE* fp, bool compact = false );
\r
1589 bool ProcessEntities() const {
\r
1590 return _processEntities;
\r
1592 Whitespace WhitespaceMode() const {
\r
1593 return _whitespace;
\r
1597 Returns true if this document has a leading Byte Order Mark of UTF8.
\r
1599 bool HasBOM() const {
\r
1602 /** Sets whether to write the BOM when writing the file.
\r
1604 void SetBOM( bool useBOM ) {
\r
1605 _writeBOM = useBOM;
\r
1608 /** Return the root element of DOM. Equivalent to FirstChildElement().
\r
1609 To get the first node, use FirstChild().
\r
1611 XMLElement* RootElement() {
\r
1612 return FirstChildElement();
\r
1614 const XMLElement* RootElement() const {
\r
1615 return FirstChildElement();
\r
1618 /** Print the Document. If the Printer is not provided, it will
\r
1619 print to stdout. If you provide Printer, this can print to a file:
\r
1621 XMLPrinter printer( fp );
\r
1622 doc.Print( &printer );
\r
1625 Or you can use a printer to print to memory:
\r
1627 XMLPrinter printer;
\r
1628 doc.Print( &printer );
\r
1629 // printer.CStr() has a const char* to the XML
\r
1632 void Print( XMLPrinter* streamer=0 ) const;
\r
1633 virtual bool Accept( XMLVisitor* visitor ) const;
\r
1636 Create a new Element associated with
\r
1637 this Document. The memory for the Element
\r
1638 is managed by the Document.
\r
1640 XMLElement* NewElement( const char* name );
\r
1642 Create a new Comment associated with
\r
1643 this Document. The memory for the Comment
\r
1644 is managed by the Document.
\r
1646 XMLComment* NewComment( const char* comment );
\r
1648 Create a new Text associated with
\r
1649 this Document. The memory for the Text
\r
1650 is managed by the Document.
\r
1652 XMLText* NewText( const char* text );
\r
1654 Create a new Declaration associated with
\r
1655 this Document. The memory for the object
\r
1656 is managed by the Document.
\r
1658 If the 'text' param is null, the standard
\r
1659 declaration is used.:
\r
1661 <?xml version="1.0" encoding="UTF-8"?>
\r
1664 XMLDeclaration* NewDeclaration( const char* text=0 );
\r
1666 Create a new Unknown associated with
\r
1667 this Document. The memory for the object
\r
1668 is managed by the Document.
\r
1670 XMLUnknown* NewUnknown( const char* text );
\r
1673 Delete a node associated with this document.
\r
1674 It will be unlinked from the DOM.
\r
1676 void DeleteNode( XMLNode* node );
\r
1678 void SetError( XMLError error, const char* str1, const char* str2 );
\r
1680 /// Return true if there was an error parsing the document.
\r
1681 bool Error() const {
\r
1682 return _errorID != XML_NO_ERROR;
\r
1684 /// Return the errorID.
\r
1685 XMLError ErrorID() const {
\r
1688 const char* ErrorName() const;
\r
1690 /// Return a possibly helpful diagnostic location or string.
\r
1691 const char* GetErrorStr1() const {
\r
1692 return _errorStr1;
\r
1694 /// Return a possibly helpful secondary diagnostic location or string.
\r
1695 const char* GetErrorStr2() const {
\r
1696 return _errorStr2;
\r
1698 /// If there is an error, print it to stdout.
\r
1699 void PrintError() const;
\r
1701 /// Clear the document, resetting it to the initial state.
\r
1705 char* Identify( char* p, XMLNode** node );
\r
1707 virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const {
\r
1710 virtual bool ShallowEqual( const XMLNode* /*compare*/ ) const {
\r
1715 XMLDocument( const XMLDocument& ); // not supported
\r
1716 void operator=( const XMLDocument& ); // not supported
\r
1719 bool _processEntities;
\r
1720 XMLError _errorID;
\r
1721 Whitespace _whitespace;
\r
1722 const char* _errorStr1;
\r
1723 const char* _errorStr2;
\r
1724 char* _charBuffer;
\r
1726 MemPoolT< sizeof(XMLElement) > _elementPool;
\r
1727 MemPoolT< sizeof(XMLAttribute) > _attributePool;
\r
1728 MemPoolT< sizeof(XMLText) > _textPool;
\r
1729 MemPoolT< sizeof(XMLComment) > _commentPool;
\r
1731 static const char* _errorNames[XML_ERROR_COUNT];
\r
1738 A XMLHandle is a class that wraps a node pointer with null checks; this is
\r
1739 an incredibly useful thing. Note that XMLHandle is not part of the TinyXML-2
\r
1740 DOM structure. It is a separate utility class.
\r
1745 <Element attributeA = "valueA">
\r
1746 <Child attributeB = "value1" />
\r
1747 <Child attributeB = "value2" />
\r
1752 Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very
\r
1753 easy to write a *lot* of code that looks like:
\r
1756 XMLElement* root = document.FirstChildElement( "Document" );
\r
1759 XMLElement* element = root->FirstChildElement( "Element" );
\r
1762 XMLElement* child = element->FirstChildElement( "Child" );
\r
1765 XMLElement* child2 = child->NextSiblingElement( "Child" );
\r
1768 // Finally do something useful.
\r
1771 And that doesn't even cover "else" cases. XMLHandle addresses the verbosity
\r
1772 of such code. A XMLHandle checks for null pointers so it is perfectly safe
\r
1773 and correct to use:
\r
1776 XMLHandle docHandle( &document );
\r
1777 XMLElement* child2 = docHandle.FirstChildElement( "Document" ).FirstChildElement( "Element" ).FirstChildElement().NextSiblingElement();
\r
1780 // do something useful
\r
1783 Which is MUCH more concise and useful.
\r
1785 It is also safe to copy handles - internally they are nothing more than node pointers.
\r
1787 XMLHandle handleCopy = handle;
\r
1790 See also XMLConstHandle, which is the same as XMLHandle, but operates on const objects.
\r
1792 class TINYXML2_LIB XMLHandle
\r
1795 /// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
\r
1796 XMLHandle( XMLNode* node ) {
\r
1799 /// Create a handle from a node.
\r
1800 XMLHandle( XMLNode& node ) {
\r
1803 /// Copy constructor
\r
1804 XMLHandle( const XMLHandle& ref ) {
\r
1805 _node = ref._node;
\r
1808 XMLHandle& operator=( const XMLHandle& ref ) {
\r
1809 _node = ref._node;
\r
1813 /// Get the first child of this handle.
\r
1814 XMLHandle FirstChild() {
\r
1815 return XMLHandle( _node ? _node->FirstChild() : 0 );
\r
1817 /// Get the first child element of this handle.
\r
1818 XMLHandle FirstChildElement( const char* name = 0 ) {
\r
1819 return XMLHandle( _node ? _node->FirstChildElement( name ) : 0 );
\r
1821 /// Get the last child of this handle.
\r
1822 XMLHandle LastChild() {
\r
1823 return XMLHandle( _node ? _node->LastChild() : 0 );
\r
1825 /// Get the last child element of this handle.
\r
1826 XMLHandle LastChildElement( const char* name = 0 ) {
\r
1827 return XMLHandle( _node ? _node->LastChildElement( name ) : 0 );
\r
1829 /// Get the previous sibling of this handle.
\r
1830 XMLHandle PreviousSibling() {
\r
1831 return XMLHandle( _node ? _node->PreviousSibling() : 0 );
\r
1833 /// Get the previous sibling element of this handle.
\r
1834 XMLHandle PreviousSiblingElement( const char* name = 0 ) {
\r
1835 return XMLHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
\r
1837 /// Get the next sibling of this handle.
\r
1838 XMLHandle NextSibling() {
\r
1839 return XMLHandle( _node ? _node->NextSibling() : 0 );
\r
1841 /// Get the next sibling element of this handle.
\r
1842 XMLHandle NextSiblingElement( const char* name = 0 ) {
\r
1843 return XMLHandle( _node ? _node->NextSiblingElement( name ) : 0 );
\r
1846 /// Safe cast to XMLNode. This can return null.
\r
1847 XMLNode* ToNode() {
\r
1850 /// Safe cast to XMLElement. This can return null.
\r
1851 XMLElement* ToElement() {
\r
1852 return ( ( _node == 0 ) ? 0 : _node->ToElement() );
\r
1854 /// Safe cast to XMLText. This can return null.
\r
1855 XMLText* ToText() {
\r
1856 return ( ( _node == 0 ) ? 0 : _node->ToText() );
\r
1858 /// Safe cast to XMLUnknown. This can return null.
\r
1859 XMLUnknown* ToUnknown() {
\r
1860 return ( ( _node == 0 ) ? 0 : _node->ToUnknown() );
\r
1862 /// Safe cast to XMLDeclaration. This can return null.
\r
1863 XMLDeclaration* ToDeclaration() {
\r
1864 return ( ( _node == 0 ) ? 0 : _node->ToDeclaration() );
\r
1873 A variant of the XMLHandle class for working with const XMLNodes and Documents. It is the
\r
1874 same in all regards, except for the 'const' qualifiers. See XMLHandle for API.
\r
1876 class TINYXML2_LIB XMLConstHandle
\r
1879 XMLConstHandle( const XMLNode* node ) {
\r
1882 XMLConstHandle( const XMLNode& node ) {
\r
1885 XMLConstHandle( const XMLConstHandle& ref ) {
\r
1886 _node = ref._node;
\r
1889 XMLConstHandle& operator=( const XMLConstHandle& ref ) {
\r
1890 _node = ref._node;
\r
1894 const XMLConstHandle FirstChild() const {
\r
1895 return XMLConstHandle( _node ? _node->FirstChild() : 0 );
\r
1897 const XMLConstHandle FirstChildElement( const char* name = 0 ) const {
\r
1898 return XMLConstHandle( _node ? _node->FirstChildElement( name ) : 0 );
\r
1900 const XMLConstHandle LastChild() const {
\r
1901 return XMLConstHandle( _node ? _node->LastChild() : 0 );
\r
1903 const XMLConstHandle LastChildElement( const char* name = 0 ) const {
\r
1904 return XMLConstHandle( _node ? _node->LastChildElement( name ) : 0 );
\r
1906 const XMLConstHandle PreviousSibling() const {
\r
1907 return XMLConstHandle( _node ? _node->PreviousSibling() : 0 );
\r
1909 const XMLConstHandle PreviousSiblingElement( const char* name = 0 ) const {
\r
1910 return XMLConstHandle( _node ? _node->PreviousSiblingElement( name ) : 0 );
\r
1912 const XMLConstHandle NextSibling() const {
\r
1913 return XMLConstHandle( _node ? _node->NextSibling() : 0 );
\r
1915 const XMLConstHandle NextSiblingElement( const char* name = 0 ) const {
\r
1916 return XMLConstHandle( _node ? _node->NextSiblingElement( name ) : 0 );
\r
1920 const XMLNode* ToNode() const {
\r
1923 const XMLElement* ToElement() const {
\r
1924 return ( ( _node == 0 ) ? 0 : _node->ToElement() );
\r
1926 const XMLText* ToText() const {
\r
1927 return ( ( _node == 0 ) ? 0 : _node->ToText() );
\r
1929 const XMLUnknown* ToUnknown() const {
\r
1930 return ( ( _node == 0 ) ? 0 : _node->ToUnknown() );
\r
1932 const XMLDeclaration* ToDeclaration() const {
\r
1933 return ( ( _node == 0 ) ? 0 : _node->ToDeclaration() );
\r
1937 const XMLNode* _node;
\r
1942 Printing functionality. The XMLPrinter gives you more
\r
1943 options than the XMLDocument::Print() method.
\r
1946 -# Print to memory.
\r
1947 -# Print to a file you provide.
\r
1948 -# Print XML without a XMLDocument.
\r
1953 XMLPrinter printer;
\r
1954 doc.Print( &printer );
\r
1955 SomeFunction( printer.CStr() );
\r
1960 You provide the file pointer.
\r
1962 XMLPrinter printer( fp );
\r
1963 doc.Print( &printer );
\r
1966 Print without a XMLDocument
\r
1968 When loading, an XML parser is very useful. However, sometimes
\r
1969 when saving, it just gets in the way. The code is often set up
\r
1970 for streaming, and constructing the DOM is just overhead.
\r
1972 The Printer supports the streaming case. The following code
\r
1973 prints out a trivially simple XML file without ever creating
\r
1977 XMLPrinter printer( fp );
\r
1978 printer.OpenElement( "foo" );
\r
1979 printer.PushAttribute( "foo", "bar" );
\r
1980 printer.CloseElement();
\r
1983 class TINYXML2_LIB XMLPrinter : public XMLVisitor
\r
1986 /** Construct the printer. If the FILE* is specified,
\r
1987 this will print to the FILE. Else it will print
\r
1988 to memory, and the result is available in CStr().
\r
1989 If 'compact' is set to true, then output is created
\r
1990 with only required whitespace and newlines.
\r
1992 XMLPrinter( FILE* file=0, bool compact = false, int depth = 0 );
\r
1993 virtual ~XMLPrinter() {}
\r
1995 /** If streaming, write the BOM and declaration. */
\r
1996 void PushHeader( bool writeBOM, bool writeDeclaration );
\r
1997 /** If streaming, start writing an element.
\r
1998 The element must be closed with CloseElement()
\r
2000 void OpenElement( const char* name, bool compactMode=false );
\r
2001 /// If streaming, add an attribute to an open element.
\r
2002 void PushAttribute( const char* name, const char* value );
\r
2003 void PushAttribute( const char* name, int value );
\r
2004 void PushAttribute( const char* name, unsigned value );
\r
2005 void PushAttribute( const char* name, bool value );
\r
2006 void PushAttribute( const char* name, double value );
\r
2007 /// If streaming, close the Element.
\r
2008 virtual void CloseElement( bool compactMode=false );
\r
2010 /// Add a text node.
\r
2011 void PushText( const char* text, bool cdata=false );
\r
2012 /// Add a text node from an integer.
\r
2013 void PushText( int value );
\r
2014 /// Add a text node from an unsigned.
\r
2015 void PushText( unsigned value );
\r
2016 /// Add a text node from a bool.
\r
2017 void PushText( bool value );
\r
2018 /// Add a text node from a float.
\r
2019 void PushText( float value );
\r
2020 /// Add a text node from a double.
\r
2021 void PushText( double value );
\r
2024 void PushComment( const char* comment );
\r
2026 void PushDeclaration( const char* value );
\r
2027 void PushUnknown( const char* value );
\r
2029 virtual bool VisitEnter( const XMLDocument& /*doc*/ );
\r
2030 virtual bool VisitExit( const XMLDocument& /*doc*/ ) {
\r
2034 virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute );
\r
2035 virtual bool VisitExit( const XMLElement& element );
\r
2037 virtual bool Visit( const XMLText& text );
\r
2038 virtual bool Visit( const XMLComment& comment );
\r
2039 virtual bool Visit( const XMLDeclaration& declaration );
\r
2040 virtual bool Visit( const XMLUnknown& unknown );
\r
2043 If in print to memory mode, return a pointer to
\r
2044 the XML file in memory.
\r
2046 const char* CStr() const {
\r
2047 return _buffer.Mem();
\r
2050 If in print to memory mode, return the size
\r
2051 of the XML file in memory. (Note the size returned
\r
2052 includes the terminating null.)
\r
2054 int CStrSize() const {
\r
2055 return _buffer.Size();
\r
2058 If in print to memory mode, reset the buffer to the
\r
2061 void ClearBuffer() {
\r
2067 virtual bool CompactMode( const XMLElement& ) { return _compactMode; }
\r
2069 /** Prints out the space before an element. You may override to change
\r
2070 the space and tabs used. A PrintSpace() override should call Print().
\r
2072 virtual void PrintSpace( int depth );
\r
2073 void Print( const char* format, ... );
\r
2075 void SealElementIfJustOpened();
\r
2076 bool _elementJustOpened;
\r
2077 DynArray< const char*, 10 > _stack;
\r
2080 void PrintString( const char*, bool restrictedEntitySet ); // prints out, after detecting entities.
\r
2082 bool _firstElement;
\r
2086 bool _processEntities;
\r
2087 bool _compactMode;
\r
2090 ENTITY_RANGE = 64,
\r
2093 bool _entityFlag[ENTITY_RANGE];
\r
2094 bool _restrictedEntityFlag[ENTITY_RANGE];
\r
2096 DynArray< char, 20 > _buffer;
\r
2102 #if defined(_MSC_VER)
\r
2103 # pragma warning(pop)
\r
2106 #endif // TINYXML2_INCLUDED
\r