tinyxml2.h
1// Original code by Lee Thomason(www.grinninglizard.com)
2//
3// This software is provided 'as-is', without any express or implied
4// warranty. In no event will the authors be held liable for any
5// damages arising from the use of this software.
6//
7// Permission is granted to anyone to use this software for any
8// purpose, including commercial applications, and to alter it and
9// redistribute it freely, subject to the following restrictions:
10//
11// 1. The origin of this software must not be misrepresented; you must
12// not claim that you wrote the original software. If you use this
13// software in a product, an acknowledgment in the product documentation
14// would be appreciated but is not required.
15//
16// 2. Altered source versions must be plainly marked as such, and
17// must not be misrepresented as being the original software.
18//
19// 3. This notice may not be removed or altered from any source
20// distribution.
21
22
23#ifndef TINYXML2_INCLUDED
24#define TINYXML2_INCLUDED
25
26#if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__)
27# include <ctype.h>
28# include <limits.h>
29# include <stdio.h>
30# include <stdlib.h>
31# include <string.h>
32# if defined(__PS3__)
33# include <stddef.h>
34# endif
35#else
36# include <cctype>
37# include <climits>
38# include <cstdio>
39# include <cstdlib>
40# include <cstring>
41#endif
42#include <stdint.h>
43
44
45// TODO: intern strings instead of allocation.
46
47
48// gcc:
49// g++ -Wall -DTINYXML2_DEBUG tinyxml2.cpp xmltest.cpp -o gccxmltest.exe
50
51// Formatting, Artistic Style:
52// AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h
53
54
55#if defined(_DEBUG ) || defined(__DEBUG__)
56# ifndef TINYXML2_DEBUG
57# define TINYXML2_DEBUG
58# endif
59#endif
60
61# pragma warning(push)
62# pragma warning(disable: 4267)
63
64#ifdef _MSC_VER
65# pragma warning(push)
66# pragma warning(disable: 4251)
67#endif
68
69#ifdef _WIN32
70# ifdef TINYXML2_EXPORT
71# define TINYXML2_LIB __declspec(dllexport)
72# elif defined(TINYXML2_IMPORT)
73# define TINYXML2_LIB __declspec(dllimport)
74# else
75# define TINYXML2_LIB
76# endif
77#elif __GNUC__ >= 4
78# define TINYXML2_LIB __attribute__((visibility("default")))
79#else
80# define TINYXML2_LIB
81#endif
82
83
84#if defined(TINYXML2_DEBUG)
85# if defined(_MSC_VER)
86# // "()0," is for suppressing C4127 warning in "assert(false)", "assert(true)" and the like
87# define TIXMLASSERT(x ) //if(!(()0,(x))) { __debugbreak(); }
88# elif defined(ANDROID_NDK)
89# include <android/log.h>
90# define TIXMLASSERT(x ) if(!(x)) { __android_log_assert("assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); }
91# else
92# include <assert.h>
93# define TIXMLASSERT assert
94# endif
95#else
96# define TIXMLASSERT(x ) {}
97#endif
98
99
100// Versioning, past 1.0.14:
101// http://semver.org/
102
103//static const int TIXML2_MAJOR_VERSION = 6;
104//static const int TIXML2_MINOR_VERSION = 1;
105//static const int TIXML2_PATCHVERSION = 0;
106
107#define TINYXML2_MAJOR_VERSION 6
108#define TINYXML2_MINOR_VERSION 1
109#define TINYXML2_PATCHVERSION 0
110
111namespace tinyxml2
112{
113class XMLDocument;
114class XMLElement;
115class XMLAttribute;
116class XMLComment;
117class XMLText;
118class XMLDeclaration;
119class XMLUnknown;
120class XMLPrinter;
121
122
123// A class that wraps strings. Normally stores the start and end
124// pointers into the XML file itself, and will apply normalization
125// and entity translation if actually read. Can also store(and memory
126// manage) a traditional char[]
127
129{
130public:
131 enum {
132 NEEDS_ENTITY_PROCESSING = 0x01,
133 NEEDS_NEWLINE_NORMALIZATION = 0x02,
134 NEEDS_WHITESPACE_COLLAPSING = 0x04,
135
136 TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
137 TEXT_ELEMENT_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
138 ATTRIBUTE_NAME = 0,
139 ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
140 ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
141 COMMENT = NEEDS_NEWLINE_NORMALIZATION
142 };
143
144 StrPair() : _flags(0 ), _start(nullptr ), _end(nullptr ) {}
145 ~StrPair();
146
147 void Set(char* start, char* end, int flags ) {
148 TIXMLASSERT(start );
149 TIXMLASSERT(end );
150 Reset();
151 _start = start;
152 _end = end;
153 _flags = flags | NEEDS_FLUSH;
154 }
155
156 const char* GetStr();
157
158 bool Empty() const {
159 return _start == _end;
160 }
161
162 void SetInternedStr(const char* str ) {
163 Reset();
164 _start = const_cast<char*>(str);
165 }
166
167 void SetStr(const char* str, int flags=0 );
168
169 char* ParseText(char* in, const char* endTag, int strFlags, int* curLineNumPtr );
170 char* ParseName(char* in );
171
172 void TransferTo(StrPair* other );
173 void Reset();
174
175private:
176 void CollapseWhitespace();
177
178 enum {
179 NEEDS_FLUSH = 0x100,
180 NEEDS_DELETE = 0x200
181 };
182
183 int _flags;
184 char* _start;
185 char* _end;
186
187 StrPair(const StrPair& other ); // not supported
188 void operator= (StrPair& other ); // not supported, use TransferTo()
189};
190
191
192
193// A dynamic array of Plain Old Data. Doesn't support constructors, etc.
194// Has a small initial memory pool, so that low or no usage will not
195// cause a call to new/delete
196
197template <class T, int INITIAL_SIZE>
199{
200public:
201 DynArray() :
202 _mem(_pool ),
203 _allocated(INITIAL_SIZE ),
204 _size(0 )
205 {
206 }
207
208 ~DynArray() {
209 if(_mem != _pool ) {
210 delete [] _mem;
211 }
212 }
213
214 void Clear() {
215 _size = 0;
216 }
217
218 void Push(T t ) {
219 TIXMLASSERT(_size < INT_MAX );
220 EnsureCapacity(_size+1 );
221 _mem[_size] = t;
222 ++_size;
223 }
224
225 T* PushArr(int count ) {
226 TIXMLASSERT(count >= 0 );
227 TIXMLASSERT(_size <= INT_MAX - count );
228 EnsureCapacity(_size+count );
229 T* ret = &_mem[_size];
230 _size += count;
231 return ret;
232 }
233
234 T Pop() {
235 TIXMLASSERT(_size > 0 );
236 --_size;
237 return _mem[_size];
238 }
239
240 void PopArr(int count ) {
241 TIXMLASSERT(_size >= count );
242 _size -= count;
243 }
244
245 bool Empty() const {
246 return _size == 0;
247 }
248
249 T& operator[](int i) {
250 TIXMLASSERT(i>= 0 && i < _size );
251 return _mem[i];
252 }
253
254 const T& operator[](int i) const {
255 TIXMLASSERT(i>= 0 && i < _size );
256 return _mem[i];
257 }
258
259 const T& PeekTop() const {
260 TIXMLASSERT(_size > 0 );
261 return _mem[ _size - 1];
262 }
263
264 int Size() const {
265 TIXMLASSERT(_size >= 0 );
266 return _size;
267 }
268
269 int Capacity() const {
270 TIXMLASSERT(_allocated >= INITIAL_SIZE );
271 return _allocated;
272 }
273
274 void SwapRemove(int i) {
275 TIXMLASSERT(i >= 0 && i < _size);
276 TIXMLASSERT(_size > 0);
277 _mem[i] = _mem[_size - 1];
278 --_size;
279 }
280
281 const T* Mem() const {
282 TIXMLASSERT(_mem );
283 return _mem;
284 }
285
286 T* Mem() {
287 TIXMLASSERT(_mem );
288 return _mem;
289 }
290
291private:
292 DynArray(const DynArray&); // not supported
293 void operator= (const DynArray&); // not supported
294
295 void EnsureCapacity(int cap ) {
296 TIXMLASSERT(cap > 0 );
297 if(cap > _allocated ) {
298 TIXMLASSERT(cap <= INT_MAX / 2 );
299 int newAllocated = cap * 2;
300 T* newMem = new T[static_cast<size_t>(newAllocated)];
301 TIXMLASSERT(newAllocated >= _size );
302 memcpy(newMem, _mem, sizeof(T)*static_cast<size_t>(_size) ); // warning: not using constructors, only works for PODs
303 if(_mem != _pool ) {
304 delete [] _mem;
305 }
306 _mem = newMem;
307 _allocated = newAllocated;
308 }
309 }
310
311 T* _mem;
312 T _pool[INITIAL_SIZE];
313 int _allocated; // objects allocated
314 int _size; // number objects in use
315};
316
317
318
319// Parent virtual class of a pool for fast allocation
320// and deallocation of objects.
321
323{
324public:
325 MemPool() {}
326 virtual ~MemPool() {}
327
328 virtual int ItemSize() const = 0;
329 virtual void* Alloc() = 0;
330 virtual void Free(void*) = 0;
331 virtual void SetTracked() = 0;
332 virtual void Clear() = 0;
333};
334
335
336
337// Template child class to create pools of the correct type.
338
339template< int ITEM_SIZE >
340class MemPoolT : public MemPool
341{
342public:
343 MemPoolT() : _blockPtrs(), _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {}
344 ~MemPoolT() {
345 Clear();
346 }
347
348 void Clear() {
349 // Delete the blocks.
350 while(!_blockPtrs.Empty()) {
351 Block* lastBlock = _blockPtrs.Pop();
352 delete lastBlock;
353 }
354 _root = 0;
355 _currentAllocs = 0;
356 _nAllocs = 0;
357 _maxAllocs = 0;
358 _nUntracked = 0;
359 }
360
361 virtual int ItemSize() const {
362 return ITEM_SIZE;
363 }
364 int CurrentAllocs() const {
365 return _currentAllocs;
366 }
367
368 virtual void* Alloc() {
369 if(!_root ) {
370 // Need a new block.
371 Block* block = new Block();
372 _blockPtrs.Push(block );
373
374 Item* blockItems = block->items;
375 for(int i = 0; i < ITEMS_PER_BLOCK - 1; ++i ) {
376 blockItems[i].next = &(blockItems[i + 1]);
377 }
378 blockItems[ITEMS_PER_BLOCK - 1].next = 0;
379 _root = blockItems;
380 }
381 Item* const result = _root;
382 TIXMLASSERT(result != 0 );
383 _root = _root->next;
384
385 ++_currentAllocs;
386 if(_currentAllocs > _maxAllocs ) {
387 _maxAllocs = _currentAllocs;
388 }
389 ++_nAllocs;
390 ++_nUntracked;
391 return result;
392 }
393
394 virtual void Free(void* mem ) {
395 if(!mem ) {
396 return;
397 }
398 --_currentAllocs;
399 Item* item = static_cast<Item*>(mem );
400#ifdef TINYXML2_DEBUG
401 memset(item, 0xfe, sizeof(*item ));
402#endif
403 item->next = _root;
404 _root = item;
405 }
406 void Trace(const char* name ) {
407 printf("Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n",
408 name, _maxAllocs, _maxAllocs * ITEM_SIZE / 1024, _currentAllocs,
409 ITEM_SIZE, _nAllocs, _blockPtrs.Size());
410 }
411
412 void SetTracked() {
413 --_nUntracked;
414 }
415
416 int Untracked() const {
417 return _nUntracked;
418 }
419
420 // This number is perf sensitive. 4k seems like a good tradeoff on my machine.
421 // The test file is large, 170k.
422 // Release: VS2010 gcc(no opt)
423 // 1k: 4000
424 // 2k: 4000
425 // 4k: 3900 21000
426 // 16k: 5200
427 // 32k: 4300
428 // 64k: 4000 21000
429 // Declared public because some compilers do not accept to use ITEMS_PER_BLOCK
430 // in private part if ITEMS_PER_BLOCK is private
431 enum { ITEMS_PER_BLOCK = (4 * 1024) / ITEM_SIZE };
432
433private:
434 MemPoolT(const MemPoolT&); // not supported
435 void operator= (const MemPoolT&); // not supported
436
437 union Item {
438 Item* next;
439 char itemData[ITEM_SIZE];
440 };
441 struct Block {
442 Item items[ITEMS_PER_BLOCK];
443 };
444 DynArray< Block*, 10 > _blockPtrs;
445 Item* _root;
446
447 int _currentAllocs;
448 int _nAllocs;
449 int _maxAllocs;
450 int _nUntracked;
451};
452
453
454
455
456// Implements the interface to the "Visitor pattern"(see the Accept() method.)
457// If you call the Accept() method, it requires being passed a XMLVisitor
458// class to handle callbacks. For nodes that contain other nodes(Document, Element)
459// you will get called with a VisitEnter/VisitExit pair. Nodes that are always leafs
460// are simply called with Visit().
461//
462// If you return 'true' from a Visit method, recursive parsing will continue. If you return
463// false, <b>no children of this node or its siblings</b> will be visited.
464//
465// All flavors of Visit methods have a default implementation that returns 'true'(continue
466// visiting). You need to only override methods that are interesting to you.
467//
468// Generally Accept() is called on the XMLDocument, although all nodes support visiting.
469//
470// You should never change the document from a callback.
471//
472// @sa XMLNode::Accept()
473
474class TINYXML2_LIB XMLVisitor
475{
476public:
477 virtual ~XMLVisitor() {}
478
480 virtual bool VisitEnter(const XMLDocument&) {
481 return true;
482 }
484 virtual bool VisitExit(const XMLDocument&) {
485 return true;
486 }
487
489 virtual bool VisitEnter(const XMLElement&, const XMLAttribute*) {
490 return true;
491 }
493 virtual bool VisitExit(const XMLElement&) {
494 return true;
495 }
496
498 virtual bool Visit(const XMLDeclaration&) {
499 return true;
500 }
502 virtual bool Visit(const XMLText&) {
503 return true;
504 }
506 virtual bool Visit(const XMLComment&) {
507 return true;
508 }
510 virtual bool Visit(const XMLUnknown&) {
511 return true;
512 }
513};
514
515// WARNING: must match XMLDocument::_errorNames[]
516enum XMLError {
517 XML_SUCCESS = 0,
518 XML_NO_ATTRIBUTE,
519 XML_WRONG_ATTRIBUTE_TYPE,
520 XML_ERROR_FILE_NOT_FOUND,
521 XML_ERROR_FILE_COULD_NOT_BE_OPENED,
522 XML_ERROR_FILE_READ_ERROR,
523 UNUSED_XML_ERROR_ELEMENT_MISMATCH, // remove at next major version
524 XML_ERROR_PARSING_ELEMENT,
525 XML_ERROR_PARSING_ATTRIBUTE,
526 UNUSED_XML_ERROR_IDENTIFYING_TAG, // remove at next major version
527 XML_ERROR_PARSING_TEXT,
528 XML_ERROR_PARSING_CDATA,
529 XML_ERROR_PARSING_COMMENT,
530 XML_ERROR_PARSING_DECLARATION,
531 XML_ERROR_PARSING_UNKNOWN,
532 XML_ERROR_EMPTY_DOCUMENT,
533 XML_ERROR_MISMATCHED_ELEMENT,
534 XML_ERROR_PARSING,
535 XML_CAN_NOT_CONVERT_TEXT,
536 XML_NO_TEXT_NODE,
537
538 XML_ERROR_COUNT
539};
540
541
542
543// Utility functionality.
544
545class TINYXML2_LIB XMLUtil
546{
547public:
548 static const char* SkipWhiteSpace(const char* p, int* curLineNumPtr ) {
549 TIXMLASSERT(p );
550
551 while(IsWhiteSpace(*p)) {
552 if(curLineNumPtr && *p == '\n') {
553 ++ (*curLineNumPtr);
554 }
555 ++p;
556 }
557 TIXMLASSERT(p );
558 return p;
559 }
560 static char* SkipWhiteSpace(char* p, int* curLineNumPtr ) {
561 return const_cast<char*>(SkipWhiteSpace(const_cast<const char*>(p), curLineNumPtr ));
562 }
563
564 // Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't
565 // correct, but simple, and usually works.
566 static bool IsWhiteSpace(char p ) {
567 return !IsUTF8Continuation(p) && isspace(static_cast<unsigned char>(p));
568 }
569
570 inline static bool IsNameStartChar(unsigned char ch ) {
571 if(ch >= 128 ) {
572 // This is a heuristic guess in attempt to not implement Unicode-aware isalpha()
573 return true;
574 }
575 if(isalpha(ch )) {
576 return true;
577 }
578 return ch == ':' || ch == '_';
579 }
580
581 inline static bool IsNameChar(unsigned char ch ) {
582 return IsNameStartChar(ch )
583 || isdigit(ch )
584 || ch == '.'
585 || ch == '-';
586 }
587
588 inline static bool StringEqual(const char* p, const char* q, int nChar=INT_MAX ) {
589 if(p == q ) {
590 return true;
591 }
592 TIXMLASSERT(p );
593 TIXMLASSERT(q );
594 TIXMLASSERT(nChar >= 0 );
595 return strncmp(p, q, static_cast<size_t>(nChar) ) == 0;
596 }
597
598 inline static bool IsUTF8Continuation(char p ) {
599 return(p & 0x80 ) != 0;
600 }
601
602 static const char* ReadBOM(const char* p, bool* hasBOM );
603 // p is the starting location,
604 // the UTF-8 value of the entity will be placed in value, and length filled in.
605 static const char* GetCharacterRef(const char* p, char* value, int* length );
606 static void ConvertUTF32ToUTF8(unsigned long input, char* output, int* length );
607
608 // converts primitive types to strings
609 static void ToStr(int v, char* buffer, int bufferSize );
610 static void ToStr(unsigned v, char* buffer, int bufferSize );
611 static void ToStr(bool v, char* buffer, int bufferSize );
612 static void ToStr(float v, char* buffer, int bufferSize );
613 static void ToStr(double v, char* buffer, int bufferSize );
614 static void ToStr(int64_t v, char* buffer, int bufferSize);
615
616 // converts strings to primitive types
617 static bool ToInt(const char* str, int* value );
618 static bool ToUnsigned(const char* str, unsigned* value );
619 static bool ToBool(const char* str, bool* value );
620 static bool ToFloat(const char* str, float* value );
621 static bool ToDouble(const char* str, double* value );
622 static bool ToInt64(const char* str, int64_t* value);
623
624 // Changes what is serialized for a boolean value.
625 // Default to "true" and "false". Shouldn't be changed
626 // unless you have a special testing or compatibility need.
627 // Be careful: static, global, & not thread safe.
628 // Be sure to set static const memory as parameters.
629 static void SetBoolSerialization(const char* writeTrue, const char* writeFalse);
630
631private:
632 static const char* writeBoolTrue;
633 static const char* writeBoolFalse;
634};
635
636
637// XMLNode is a base class for every object that is in the
638// XML Document Object Model(DOM), except XMLAttributes.
639// Nodes have siblings, a parent, and children which can
640// be navigated. A node is always in a XMLDocument.
641// The type of a XMLNode can be queried, and it can
642// be cast to its more defined type.
643//
644// A XMLDocument allocates memory for all its Nodes.
645// When the XMLDocument gets deleted, all its Nodes
646// will also be deleted.
647//
648// @verbatim
649// A Document can contain: Element (container or leaf)
650// Comment(leaf)
651// Unknown(leaf)
652// Declaration(leaf )
653//
654// An Element can contain: Element(container or leaf)
655// Text (leaf)
656// Attributes(not on tree)
657// Comment(leaf)
658// Unknown(leaf)
659//
660// @endverbatim
661
662class TINYXML2_LIB XMLNode
663{
664 friend class XMLDocument;
665 friend class XMLElement;
666public:
667
669 const XMLDocument* GetDocument() const {
670 TIXMLASSERT(_document );
671 return _document;
672 }
675 TIXMLASSERT(_document );
676 return _document;
677 }
678
681 return nullptr;
682 }
684 virtual XMLText* ToText() {
685 return nullptr;
686 }
689 return nullptr;
690 }
693 return nullptr;
694 }
697 return nullptr;
698 }
701 return nullptr;
702 }
703
704 virtual const XMLElement* ToElement() const {
705 return nullptr;
706 }
707 virtual const XMLText* ToText() const {
708 return nullptr;
709 }
710 virtual const XMLComment* ToComment() const {
711 return nullptr;
712 }
713 virtual const XMLDocument* ToDocument() const {
714 return nullptr;
715 }
716 virtual const XMLDeclaration* ToDeclaration() const {
717 return nullptr;
718 }
719 virtual const XMLUnknown* ToUnknown() const {
720 return nullptr;
721 }
722
723// The meaning of 'value' changes for the specific type.
724// @verbatim
725// Document: empty(nullptr is returned, not an empty string)
726// Element: name of the element
727// Comment: the comment text
728// Unknown: the tag contents
729// Text: the text string
730// @endverbatim
731
732 const char* Value() const;
733
734// Set the Value of an XML node.
735// @sa Value()
736
737 void SetValue(const char* val, bool staticMem=false );
738
740 int GetLineNum() const { return _parseLineNum; }
741
743 const XMLNode* Parent() const {
744 return _parent;
745 }
746
747 XMLNode* Parent() {
748 return _parent;
749 }
750
752 bool NoChildren() const {
753 return !_firstChild;
754 }
755
757 const XMLNode* FirstChild() const {
758 return _firstChild;
759 }
760
761 XMLNode* FirstChild() {
762 return _firstChild;
763 }
764
765// Get the first child element, or optionally the first child
766// element with the specified name.
767
768 const XMLElement* FirstChildElement(const char* name = nullptr ) const;
769
770 XMLElement* FirstChildElement(const char* name = nullptr ) {
771 return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->FirstChildElement(name ));
772 }
773
775 const XMLNode* LastChild() const {
776 return _lastChild;
777 }
778
779 XMLNode* LastChild() {
780 return _lastChild;
781 }
782
783// Get the last child element or optionally the last child
784// element with the specified name.
785
786 const XMLElement* LastChildElement(const char* name = nullptr ) const;
787
788 XMLElement* LastChildElement(const char* name = nullptr ) {
789 return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->LastChildElement(name));
790 }
791
793 const XMLNode* PreviousSibling() const {
794 return _prev;
795 }
796
797 XMLNode* PreviousSibling() {
798 return _prev;
799 }
800
802 const XMLElement* PreviousSiblingElement(const char* name = nullptr ) const;
803
804 XMLElement* PreviousSiblingElement(const char* name = nullptr ) {
805 return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->PreviousSiblingElement(name ));
806 }
807
809 const XMLNode* NextSibling() const {
810 return _next;
811 }
812
813 XMLNode* NextSibling() {
814 return _next;
815 }
816
818 const XMLElement* NextSiblingElement(const char* name = nullptr ) const;
819
820 XMLElement* NextSiblingElement(const char* name = nullptr ) {
821 return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->NextSiblingElement(name ));
822 }
823
824
825// Add a child node as the last(right) child.
826// If the child node is already part of the document,
827// it is moved from its old location to the new location.
828// Returns the addThis argument or 0 if the node does not
829// belong to the same document.
830
831 XMLNode* InsertEndChild(XMLNode* addThis );
832
833 XMLNode* LinkEndChild(XMLNode* addThis ) {
834 return InsertEndChild(addThis );
835 }
836
837// Add a child node as the first(left) child.
838// If the child node is already part of the document,
839// it is moved from its old location to the new location.
840// Returns the addThis argument or 0 if the node does not
841// belong to the same document.
842
843 XMLNode* InsertFirstChild(XMLNode* addThis );
844
845// Add a node after the specified child node.
846// If the child node is already part of the document,
847// it is moved from its old location to the new location.
848// Returns the addThis argument or 0 if the afterThis node
849// is not a child of this node, or if the node does not
850// belong to the same document.
851
852 XMLNode* InsertAfterChild(XMLNode* afterThis, XMLNode* addThis );
853
854
855// Delete all the children of this node.
856
857 void DeleteChildren();
858
859
860// Delete a child of this node.
861
862 void DeleteChild(XMLNode* node );
863
864
865// Make a copy of this node, but not its children.
866// You may pass in a Document pointer that will be
867// the owner of the new Node. If the 'document' is
868// null, then the node returned will be allocated
869// from the current Document.(this->GetDocument())
870//
871// Note: if called on a XMLDocument, this will return null.
872
873 virtual XMLNode* ShallowClone(XMLDocument* document ) const = 0;
874
875
876// Make a copy of this node and all its children.
877//
878// If the 'target' is null, then the nodes will
879// be allocated in the current document. If 'target'
880// is specified, the memory will be allocated is the
881// specified XMLDocument.
882//
883// NOTE: This is probably not the correct tool to
884// copy a document, since XMLDocuments can have multiple
885// top level XMLNodes. You probably want to use
886// XMLDocument::DeepCopy()
887
888 XMLNode* DeepClone(XMLDocument* target ) const;
889
890
891// Test if 2 nodes are the same, but don't test children.
892// The 2 nodes do not need to be in the same Document.
893//
894// Note: if called on a XMLDocument, this will return false.
895
896 virtual bool ShallowEqual(const XMLNode* compare ) const = 0;
897
898// Accept a hierarchical visit of the nodes in the TinyXML-2 DOM. Every node in the
899// XML tree will be conditionally visited and the host will be called back
900// via the XMLVisitor interface.
901//
902// This is essentially a SAX interface for TinyXML-2.(Note however it doesn't re-parse
903// the XML for the callbacks, so the performance of TinyXML-2 is unchanged by using this
904// interface versus any other.)
905//
906// The interface has been based on ideas from:
907//
908// - http://www.saxproject.org/
909// - http://c2.com/cgi/wiki?HierarchicalVisitorPattern
910//
911// Which are both good references for "visiting".
912//
913// An example of using Accept():
914// @verbatim
915// XMLPrinter printer;
916// tinyxmlDoc.Accept(&printer );
917// const char* xmlcstr = printer.CStr();
918// @endverbatim
919
920 virtual bool Accept(XMLVisitor* visitor ) const = 0;
921
922
923// Set user data into the XMLNode. TinyXML-2 in
924// no way processes or interprets user data.
925// It is initially 0.
926
927 void SetUserData(void* userData) { _userData = userData; }
928
929
930// Get user data set into the XMLNode. TinyXML-2 in
931// no way processes or interprets user data.
932// It is initially 0.
933
934 void* GetUserData() const { return _userData; }
935
936protected:
937 XMLNode(XMLDocument*);
938 virtual ~XMLNode();
939
940 virtual char* ParseDeep(char* p, StrPair* parentEndTag, int* curLineNumPtr);
941
942 XMLDocument* _document;
943 XMLNode* _parent;
944 mutable StrPair _value;
945 int _parseLineNum;
946
947 XMLNode* _firstChild;
948 XMLNode* _lastChild;
949
950 XMLNode* _prev;
951 XMLNode* _next;
952
953 void* _userData;
954
955private:
956 MemPool* _memPool;
957 void Unlink(XMLNode* child );
958 static void DeleteNode(XMLNode* node );
959 void InsertChildPreamble(XMLNode* insertThis ) const;
960 const XMLElement* ToElementWithName(const char* name ) const;
961
962 XMLNode(const XMLNode&); // not supported
963 XMLNode& operator= (const XMLNode&); // not supported
964};
965
966
967// XML text.
968//
969// Note that a text node can have child element nodes, for example:
970// @verbatim
971// <root>This is <b>bold</b></root>
972// @endverbatim
973//
974// A text node can have 2 ways to output the next. "normal" output
975// and CDATA. It will default to the mode it was parsed from the XML file and
976// you generally want to leave it alone, but you can change the output mode with
977// SetCData() and query it with CData().
978
979class TINYXML2_LIB XMLText : public XMLNode
980{
981 friend class XMLDocument;
982public:
983 virtual bool Accept(XMLVisitor* visitor ) const;
984
985 virtual XMLText* ToText() {
986 return this;
987 }
988 virtual const XMLText* ToText() const {
989 return this;
990 }
991
993 void SetCData(bool isCData ) {
994 _isCData = isCData;
995 }
997 bool CData() const {
998 return _isCData;
999 }
1000
1001 virtual XMLNode* ShallowClone(XMLDocument* document ) const;
1002 virtual bool ShallowEqual(const XMLNode* compare ) const;
1003
1004protected:
1005 XMLText(XMLDocument* doc ) : XMLNode(doc ), _isCData(false ) {}
1006 virtual ~XMLText() {}
1007
1008 char* ParseDeep(char* p, StrPair* parentEndTag, int* curLineNumPtr );
1009
1010private:
1011 bool _isCData;
1012
1013 XMLText(const XMLText&); // not supported
1014 XMLText& operator= (const XMLText&); // not supported
1015};
1016
1017
1018// An XML Comment.
1019class TINYXML2_LIB XMLComment : public XMLNode
1020{
1021 friend class XMLDocument;
1022public:
1024 return this;
1025 }
1026 virtual const XMLComment* ToComment() const {
1027 return this;
1028 }
1029
1030 virtual bool Accept(XMLVisitor* visitor ) const;
1031
1032 virtual XMLNode* ShallowClone(XMLDocument* document ) const;
1033 virtual bool ShallowEqual(const XMLNode* compare ) const;
1034
1035protected:
1036 XMLComment(XMLDocument* doc );
1037 virtual ~XMLComment();
1038
1039 char* ParseDeep(char* p, StrPair* parentEndTag, int* curLineNumPtr);
1040
1041private:
1042 XMLComment(const XMLComment&); // not supported
1043 XMLComment& operator= (const XMLComment&); // not supported
1044};
1045
1046
1047// In correct XML the declaration is the first entry in the file.
1048// @verbatim
1049// <?xml version="1.0" standalone="yes"?>
1050// @endverbatim
1051//
1052// TinyXML-2 will happily read or write files without a declaration,
1053// however.
1054//
1055// The text of the declaration isn't interpreted. It is parsed
1056// and written as a string.
1057
1058class TINYXML2_LIB XMLDeclaration : public XMLNode
1059{
1060 friend class XMLDocument;
1061public:
1063 return this;
1064 }
1065 virtual const XMLDeclaration* ToDeclaration() const {
1066 return this;
1067 }
1068
1069 virtual bool Accept(XMLVisitor* visitor ) const;
1070
1071 virtual XMLNode* ShallowClone(XMLDocument* document ) const;
1072 virtual bool ShallowEqual(const XMLNode* compare ) const;
1073
1074protected:
1075 XMLDeclaration(XMLDocument* doc );
1076 virtual ~XMLDeclaration();
1077
1078 char* ParseDeep(char* p, StrPair* parentEndTag, int* curLineNumPtr );
1079
1080private:
1081 XMLDeclaration(const XMLDeclaration&); // not supported
1082 XMLDeclaration& operator= (const XMLDeclaration&); // not supported
1083};
1084
1085
1086// Any tag that TinyXML-2 doesn't recognize is saved as an
1087// unknown. It is a tag of text, but should not be modified.
1088// It will be written back to the XML, unchanged, when the file
1089// is saved.
1090//
1091// DTD tags get thrown into XMLUnknowns.
1092
1093class TINYXML2_LIB XMLUnknown : public XMLNode
1094{
1095 friend class XMLDocument;
1096public:
1098 return this;
1099 }
1100 virtual const XMLUnknown* ToUnknown() const {
1101 return this;
1102 }
1103
1104 virtual bool Accept(XMLVisitor* visitor ) const;
1105
1106 virtual XMLNode* ShallowClone(XMLDocument* document ) const;
1107 virtual bool ShallowEqual(const XMLNode* compare ) const;
1108
1109protected:
1110 XMLUnknown(XMLDocument* doc );
1111 virtual ~XMLUnknown();
1112
1113 char* ParseDeep(char* p, StrPair* parentEndTag, int* curLineNumPtr );
1114
1115private:
1116 XMLUnknown(const XMLUnknown&); // not supported
1117 XMLUnknown& operator= (const XMLUnknown&); // not supported
1118};
1119
1120
1121
1122// An attribute is a name-value pair. Elements have an arbitrary
1123// number of attributes, each with a unique name.
1124//
1125// @note The attributes are not XMLNodes. You may only query the
1126// Next() attribute in a list.
1127
1128class TINYXML2_LIB XMLAttribute
1129{
1130 friend class XMLElement;
1131public:
1133 const char* Name() const;
1134
1136 const char* Value() const;
1137
1139 int GetLineNum() const { return _parseLineNum; }
1140
1142 const XMLAttribute* Next() const {
1143 return _next;
1144 }
1145
1146// IntValue interprets the attribute as an integer, and returns the value.
1147// If the value isn't an integer, 0 will be returned. There is no error checking;
1148// use QueryIntValue() if you need error checking.
1149
1150 int IntValue() const {
1151 int i = 0;
1152 QueryIntValue(&i);
1153 return i;
1154 }
1155
1156 int64_t Int64Value() const {
1157 int64_t i = 0;
1158 QueryInt64Value(&i);
1159 return i;
1160 }
1161
1163 unsigned UnsignedValue() const {
1164 unsigned i = 0;
1165 QueryUnsignedValue(&i );
1166 return i;
1167 }
1169 bool BoolValue() const {
1170 bool b=false;
1171 QueryBoolValue(&b );
1172 return b;
1173 }
1175 double DoubleValue() const {
1176 double d=0;
1177 QueryDoubleValue(&d );
1178 return d;
1179 }
1181 float FloatValue() const {
1182 float f=0;
1183 QueryFloatValue(&f );
1184 return f;
1185 }
1186
1187// QueryIntValue interprets the attribute as an integer, and returns the value
1188// in the provided parameter. The function will return XML_SUCCESS on success,
1189// and XML_WRONG_ATTRIBUTE_TYPE if the conversion is not successful.
1190
1191 XMLError QueryIntValue(int* value ) const;
1193 XMLError QueryUnsignedValue(unsigned int* value ) const;
1195 XMLError QueryInt64Value(int64_t* value) const;
1197 XMLError QueryBoolValue(bool* value ) const;
1199 XMLError QueryDoubleValue(double* value ) const;
1201 XMLError QueryFloatValue(float* value ) const;
1202
1204 void SetAttribute(const char* value );
1206 void SetAttribute(int value );
1208 void SetAttribute(unsigned value );
1210 void SetAttribute(int64_t value);
1212 void SetAttribute(bool value );
1214 void SetAttribute(double value );
1216 void SetAttribute(float value );
1217
1218private:
1219 enum { BUF_SIZE = 200 };
1220
1221 XMLAttribute() : _name(), _value(),_parseLineNum(0 ), _next(nullptr ), _memPool(nullptr ) {}
1222 virtual ~XMLAttribute() {}
1223
1224 XMLAttribute(const XMLAttribute&); // not supported
1225 void operator= (const XMLAttribute&); // not supported
1226 void SetName(const char* name );
1227
1228 char* ParseDeep(char* p, bool processEntities, int* curLineNumPtr );
1229
1230 mutable StrPair _name;
1231 mutable StrPair _value;
1232 int _parseLineNum;
1233 XMLAttribute* _next;
1234 MemPool* _memPool;
1235};
1236
1237
1238// The element is a container class. It has a value, the element name,
1239// and can contain other elements, text, comments, and unknowns.
1240// Elements also contain an arbitrary number of attributes.
1241
1242class TINYXML2_LIB XMLElement : public XMLNode
1243{
1244 friend class XMLDocument;
1245public:
1247 const char* Name() const {
1248 return Value();
1249 }
1251 void SetName(const char* str, bool staticMem=false ) {
1252 SetValue(str, staticMem );
1253 }
1254
1256 return this;
1257 }
1258 virtual const XMLElement* ToElement() const {
1259 return this;
1260 }
1261 virtual bool Accept(XMLVisitor* visitor ) const;
1262
1263// Given an attribute name, Attribute() returns the value
1264// for the attribute of that name, or null if none
1265// exists. For example:
1266//
1267// @verbatim
1268// const char* value = ele->Attribute("foo");
1269// @endverbatim
1270//
1271// The 'value' parameter is normally null. However, if specified,
1272// the attribute will only be returned if the 'name' and 'value'
1273// match. This allow you to write code:
1274//
1275// @verbatim
1276// if(ele->Attribute("foo", "bar")) callFooIsBar();
1277// @endverbatim
1278//
1279// rather than:
1280// @verbatim
1281// if(ele->Attribute("foo")) {
1282// if(strcmp(ele->Attribute("foo"), "bar") == 0 ) callFooIsBar();
1283// }
1284// @endverbatim
1285
1286 const char* Attribute(const char* name, const char* value=nullptr ) const;
1287
1288// Given an attribute name, IntAttribute() returns the value
1289// of the attribute interpreted as an integer. The default
1290// value will be returned if the attribute isn't present,
1291// or if there is an error.(For a method with error
1292// checking, see QueryIntAttribute()).
1293
1294 int IntAttribute(const char* name, int defaultValue = 0) const;
1296 unsigned UnsignedAttribute(const char* name, unsigned defaultValue = 0) const;
1298 int64_t Int64Attribute(const char* name, int64_t defaultValue = 0) const;
1300 bool BoolAttribute(const char* name, bool defaultValue = false) const;
1302 double DoubleAttribute(const char* name, double defaultValue = 0) const;
1304 float FloatAttribute(const char* name, float defaultValue = 0) const;
1305
1306// Given an attribute name, QueryIntAttribute() returns
1307// XML_SUCCESS, XML_WRONG_ATTRIBUTE_TYPE if the conversion
1308// can't be performed, or XML_NO_ATTRIBUTE if the attribute
1309// doesn't exist. If successful, the result of the conversion
1310// will be written to 'value'. If not successful, nothing will
1311// be written to 'value'. This allows you to provide default
1312// value:
1313//
1314// @verbatim
1315// int value = 10;
1316// QueryIntAttribute("foo", &value ); // if "foo" isn't found, value will still be 10
1317// @endverbatim
1318
1319 XMLError QueryIntAttribute(const char* name, int* value ) const {
1320 const XMLAttribute* a = FindAttribute(name );
1321 if(!a ) {
1322 return XML_NO_ATTRIBUTE;
1323 }
1324 return a->QueryIntValue(value );
1325 }
1326
1328 XMLError QueryUnsignedAttribute(const char* name, unsigned int* value ) const {
1329 const XMLAttribute* a = FindAttribute(name );
1330 if(!a ) {
1331 return XML_NO_ATTRIBUTE;
1332 }
1333 return a->QueryUnsignedValue(value );
1334 }
1335
1337 XMLError QueryInt64Attribute(const char* name, int64_t* value) const {
1338 const XMLAttribute* a = FindAttribute(name);
1339 if(!a) {
1340 return XML_NO_ATTRIBUTE;
1341 }
1342 return a->QueryInt64Value(value);
1343 }
1344
1346 XMLError QueryBoolAttribute(const char* name, bool* value ) const {
1347 const XMLAttribute* a = FindAttribute(name );
1348 if(!a ) {
1349 return XML_NO_ATTRIBUTE;
1350 }
1351 return a->QueryBoolValue(value );
1352 }
1354 XMLError QueryDoubleAttribute(const char* name, double* value ) const {
1355 const XMLAttribute* a = FindAttribute(name );
1356 if(!a ) {
1357 return XML_NO_ATTRIBUTE;
1358 }
1359 return a->QueryDoubleValue(value );
1360 }
1362 XMLError QueryFloatAttribute(const char* name, float* value ) const {
1363 const XMLAttribute* a = FindAttribute(name );
1364 if(!a ) {
1365 return XML_NO_ATTRIBUTE;
1366 }
1367 return a->QueryFloatValue(value );
1368 }
1369
1371 XMLError QueryStringAttribute(const char* name, const char** value) const {
1372 const XMLAttribute* a = FindAttribute(name);
1373 if(!a) {
1374 return XML_NO_ATTRIBUTE;
1375 }
1376 *value = a->Value();
1377 return XML_SUCCESS;
1378 }
1379
1380
1381
1382// Given an attribute name, QueryAttribute() returns
1383// XML_SUCCESS, XML_WRONG_ATTRIBUTE_TYPE if the conversion
1384// can't be performed, or XML_NO_ATTRIBUTE if the attribute
1385// doesn't exist. It is overloaded for the primitive types,
1386// and is a generally more convenient replacement of
1387// QueryIntAttribute() and related functions.
1388//
1389// If successful, the result of the conversion
1390// will be written to 'value'. If not successful, nothing will
1391// be written to 'value'. This allows you to provide default
1392// value:
1393//
1394// @verbatim
1395// int value = 10;
1396// QueryAttribute("foo", &value ); // if "foo" isn't found, value will still be 10
1397// @endverbatim
1398
1399 int QueryAttribute(const char* name, int* value ) const {
1400 return QueryIntAttribute(name, value );
1401 }
1402
1403 int QueryAttribute(const char* name, unsigned int* value ) const {
1404 return QueryUnsignedAttribute(name, value );
1405 }
1406
1407 int QueryAttribute(const char* name, int64_t* value) const {
1408 return QueryInt64Attribute(name, value);
1409 }
1410
1411 int QueryAttribute(const char* name, bool* value ) const {
1412 return QueryBoolAttribute(name, value );
1413 }
1414
1415 int QueryAttribute(const char* name, double* value ) const {
1416 return QueryDoubleAttribute(name, value );
1417 }
1418
1419 int QueryAttribute(const char* name, float* value ) const {
1420 return QueryFloatAttribute(name, value );
1421 }
1422
1424 void SetAttribute(const char* name, const char* value ) {
1425 XMLAttribute* a = FindOrCreateAttribute(name );
1426 a->SetAttribute(value );
1427 }
1429 void SetAttribute(const char* name, int value ) {
1430 XMLAttribute* a = FindOrCreateAttribute(name );
1431 a->SetAttribute(value );
1432 }
1434 void SetAttribute(const char* name, unsigned value ) {
1435 XMLAttribute* a = FindOrCreateAttribute(name );
1436 a->SetAttribute(value );
1437 }
1438
1440 void SetAttribute(const char* name, int64_t value) {
1441 XMLAttribute* a = FindOrCreateAttribute(name);
1442 a->SetAttribute(value);
1443 }
1444
1446 void SetAttribute(const char* name, bool value ) {
1447 XMLAttribute* a = FindOrCreateAttribute(name );
1448 a->SetAttribute(value );
1449 }
1451 void SetAttribute(const char* name, double value ) {
1452 XMLAttribute* a = FindOrCreateAttribute(name );
1453 a->SetAttribute(value );
1454 }
1456 void SetAttribute(const char* name, float value ) {
1457 XMLAttribute* a = FindOrCreateAttribute(name );
1458 a->SetAttribute(value );
1459 }
1460
1461
1462// Delete an attribute.
1463
1464 void DeleteAttribute(const char* name );
1465
1468 return _rootAttribute;
1469 }
1471 const XMLAttribute* FindAttribute(const char* name ) const;
1472
1473// Convenience function for easy access to the text inside an element. Although easy
1474// and concise, GetText() is limited compared to getting the XMLText child
1475// and accessing it directly.
1476//
1477// If the first child of 'this' is a XMLText, the GetText()
1478// returns the character string of the Text node, else null is returned.
1479//
1480// This is a convenient method for getting the text of simple contained text:
1481// @verbatim
1482// <foo>This is text</foo>
1483// const char* str = fooElement->GetText();
1484// @endverbatim
1485//
1486// 'str' will be a pointer to "This is text".
1487//
1488// Note that this function can be misleading. If the element foo was created from
1489// this XML:
1490// @verbatim
1491// <foo><b>This is text</b></foo>
1492// @endverbatim
1493//
1494// then the value of str would be null. The first child node isn't a text node, it is
1495// another element. From this XML:
1496// @verbatim
1497// <foo>This is <b>text</b></foo>
1498// @endverbatim
1499// GetText() will return "This is ".
1500
1501 const char* GetText() const;
1502
1503// Convenience function for easy access to the text inside an element. Although easy
1504// and concise, SetText() is limited compared to creating an XMLText child
1505// and mutating it directly.
1506//
1507// If the first child of 'this' is a XMLText, SetText() sets its value to
1508// the given string, otherwise it will create a first child that is an XMLText.
1509//
1510// This is a convenient method for setting the text of simple contained text:
1511// @verbatim
1512// <foo>This is text</foo>
1513// fooElement->SetText("Hullaballoo!");
1514// <foo>Hullaballoo!</foo>
1515// @endverbatim
1516//
1517// Note that this function can be misleading. If the element foo was created from
1518// this XML:
1519// @verbatim
1520// <foo><b>This is text</b></foo>
1521// @endverbatim
1522//
1523// then it will not change "This is text", but rather prefix it with a text element:
1524// @verbatim
1525// <foo>Hullaballoo!<b>This is text</b></foo>
1526// @endverbatim
1527//
1528// For this XML:
1529// @verbatim
1530// <foo />
1531// @endverbatim
1532// SetText() will generate
1533// @verbatim
1534// <foo>Hullaballoo!</foo>
1535// @endverbatim
1536
1537 void SetText(const char* inText );
1539 void SetText(int value );
1541 void SetText(unsigned value );
1543 void SetText(int64_t value);
1545 void SetText(bool value );
1547 void SetText(double value );
1549 void SetText(float value );
1550
1551
1552// Convenience method to query the value of a child text node. This is probably best
1553// shown by example. Given you have a document is this form:
1554// @verbatim
1555// <point>
1556// <x>1</x>
1557// <y>1.4</y>
1558// </point>
1559// @endverbatim
1560//
1561// The QueryIntText() and similar functions provide a safe and easier way to get to the
1562// "value" of x and y.
1563//
1564// @verbatim
1565// int x = 0;
1566// float y = 0; // types of x and y are contrived for example
1567// const XMLElement* xElement = pointElement->FirstChildElement("x");
1568// const XMLElement* yElement = pointElement->FirstChildElement("y");
1569// xElement->QueryIntText(&x );
1570// yElement->QueryFloatText(&y );
1571// @endverbatim
1572//
1573// @returns XML_SUCCESS(0) on success, XML_CAN_NOT_CONVERT_TEXT if the text cannot be converted
1574// to the requested type, and XML_NO_TEXT_NODE if there is no child text to query.
1575
1576
1577 XMLError QueryIntText(int* ival ) const;
1579 XMLError QueryUnsignedText(unsigned* uval ) const;
1581 XMLError QueryInt64Text(int64_t* uval) const;
1583 XMLError QueryBoolText(bool* bval ) const;
1585 XMLError QueryDoubleText(double* dval ) const;
1587 XMLError QueryFloatText(float* fval ) const;
1588
1589 int IntText(int defaultValue = 0) const;
1590
1592 unsigned UnsignedText(unsigned defaultValue = 0) const;
1594 int64_t Int64Text(int64_t defaultValue = 0) const;
1596 bool BoolText(bool defaultValue = false) const;
1598 double DoubleText(double defaultValue = 0) const;
1600 float FloatText(float defaultValue = 0) const;
1601
1602 // internal:
1603 enum ElementClosingType {
1604 OPEN, // <foo>
1605 CLOSED, // <foo/>
1606 CLOSING // </foo>
1607 };
1608 ElementClosingType ClosingType() const {
1609 return _closingType;
1610 }
1611 virtual XMLNode* ShallowClone(XMLDocument* document ) const;
1612 virtual bool ShallowEqual(const XMLNode* compare ) const;
1613
1614protected:
1615 char* ParseDeep(char* p, StrPair* parentEndTag, int* curLineNumPtr );
1616
1617private:
1618 XMLElement(XMLDocument* doc );
1619 virtual ~XMLElement();
1620 XMLElement(const XMLElement&); // not supported
1621 void operator= (const XMLElement&); // not supported
1622
1623 XMLAttribute* FindAttribute(const char* name ) {
1624 return const_cast<XMLAttribute*>(const_cast<const XMLElement*>(this)->FindAttribute(name ));
1625 }
1626 XMLAttribute* FindOrCreateAttribute(const char* name );
1627 //void LinkAttribute(XMLAttribute* attrib );
1628 char* ParseAttributes(char* p, int* curLineNumPtr );
1629 static void DeleteAttribute(XMLAttribute* attribute );
1630 XMLAttribute* CreateAttribute();
1631
1632 enum { BUF_SIZE = 200 };
1633 ElementClosingType _closingType;
1634 // The attribute list is ordered; there is no 'lastAttribute'
1635 // because the list needs to be scanned for dupes before adding
1636 // a new attribute.
1637 XMLAttribute* _rootAttribute;
1638};
1639
1640
1641enum Whitespace {
1642 PRESERVE_WHITESPACE,
1643 COLLAPSE_WHITESPACE
1644};
1645
1646
1647// A Document binds together all the functionality.
1648// It can be saved, loaded, and printed to the screen.
1649// All Nodes are connected and allocated to a Document.
1650// If the Document is deleted, all its Nodes are also deleted.
1651
1652class TINYXML2_LIB XMLDocument : public XMLNode
1653{
1654 friend class XMLElement;
1655 // Gives access to SetError, but over-access for everything else.
1656 // Wishing C++ had "internal" scope.
1657 friend class XMLNode;
1658 friend class XMLText;
1659 friend class XMLComment;
1660 friend class XMLDeclaration;
1661 friend class XMLUnknown;
1662public:
1664 XMLDocument(bool processEntities = true, Whitespace whitespaceMode = PRESERVE_WHITESPACE );
1665 ~XMLDocument();
1666
1668 TIXMLASSERT(this == _document );
1669 return this;
1670 }
1671 virtual const XMLDocument* ToDocument() const {
1672 TIXMLASSERT(this == _document );
1673 return this;
1674 }
1675
1676
1677// Parse an XML file from a character string.
1678// Returns XML_SUCCESS(0) on success, or
1679// an errorID.
1680//
1681// You may optionally pass in the 'nBytes', which is
1682// the number of bytes which will be parsed. If not
1683// specified, TinyXML-2 will assume 'xml' points to a
1684// null terminated string.
1685
1686 XMLError Parse(const char* xml, int nBytes= static_cast<int>(-1));
1687
1688
1689// Load an XML file from disk.
1690// Returns XML_SUCCESS(0) on success, or
1691// an errorID.
1692
1693 XMLError LoadFile(const char* filename );
1694
1695
1696// Load an XML file from disk. You are responsible
1697// for providing and closing the FILE*.
1698//
1699// NOTE: The file should be opened as binary("rb")
1700// not text in order for TinyXML-2 to correctly
1701// do newline normalization.
1702//
1703// Returns XML_SUCCESS(0) on success, or
1704// an errorID.
1705
1706 XMLError LoadFile(FILE*);
1707
1708
1709// Save the XML file to disk.
1710// Returns XML_SUCCESS(0) on success, or
1711// an errorID.
1712
1713 XMLError SaveFile(const char* filename, bool compact = false );
1714
1715
1716// Save the XML file to disk. You are responsible
1717// for providing and closing the FILE*.
1718//
1719// Returns XML_SUCCESS(0) on success, or
1720// an errorID.
1721
1722 XMLError SaveFile(FILE* fp, bool compact = false );
1723
1724 bool ProcessEntities() const {
1725 return _processEntities;
1726 }
1727 Whitespace WhitespaceMode() const {
1728 return _whitespaceMode;
1729 }
1730
1731
1732// Returns true if this document has a leading Byte Order Mark of UTF8.
1733
1734 bool HasBOM() const {
1735 return _writeBOM;
1736 }
1737
1738// Sets whether to write the BOM when writing the file.
1739
1740 void SetBOM(bool useBOM ) {
1741 _writeBOM = useBOM;
1742 }
1743
1744// Return the root element of DOM. Equivalent to FirstChildElement().
1745// To get the first node, use FirstChild().
1746
1747 XMLElement* RootElement() {
1748 return FirstChildElement();
1749 }
1750 const XMLElement* RootElement() const {
1751 return FirstChildElement();
1752 }
1753
1754// Print the Document. If the Printer is not provided, it will
1755// print to stdout. If you provide Printer, this can print to a file:
1756// @verbatim
1757// XMLPrinter printer(fp );
1758// doc.Print(&printer );
1759// @endverbatim
1760//
1761// Or you can use a printer to print to memory:
1762// @verbatim
1763// XMLPrinter printer;
1764// doc.Print(&printer );
1765 // printer.CStr() has a const char* to the XML
1766// @endverbatim
1767
1768 void Print(XMLPrinter* streamer=nullptr ) const;
1769 virtual bool Accept(XMLVisitor* visitor ) const;
1770
1771
1772// Create a new Element associated with
1773// this Document. The memory for the Element
1774// is managed by the Document.
1775
1776 XMLElement* NewElement(const char* name );
1777
1778// Create a new Comment associated with
1779// this Document. The memory for the Comment
1780// is managed by the Document.
1781
1782 XMLComment* NewComment(const char* comment );
1783
1784// Create a new Text associated with
1785// this Document. The memory for the Text
1786// is managed by the Document.
1787
1788 XMLText* NewText(const char* text );
1789
1790// Create a new Declaration associated with
1791// this Document. The memory for the object
1792// is managed by the Document.
1793//
1794// If the 'text' param is null, the standard
1795// declaration is used.:
1796// @verbatim
1797// <?xml version="1.0" encoding="UTF-8"?>
1798// @endverbatim
1799
1800 XMLDeclaration* NewDeclaration(const char* text=nullptr );
1801
1802// Create a new Unknown associated with
1803// this Document. The memory for the object
1804// is managed by the Document.
1805
1806 XMLUnknown* NewUnknown(const char* text );
1807
1808
1809// Delete a node associated with this document.
1810// It will be unlinked from the DOM.
1811
1812 void DeleteNode(XMLNode* node );
1813
1814 void ClearError() {
1815 SetError(XML_SUCCESS, 0, nullptr);
1816 }
1817
1819 bool Error() const {
1820 return _errorID != XML_SUCCESS;
1821 }
1823 XMLError ErrorID() const {
1824 return _errorID;
1825 }
1826 const char* ErrorName() const;
1827 static const char* ErrorIDToName(XMLError errorID);
1828
1829// Returns a "long form" error description. A hopefully helpful
1830// diagnostic with location, line number, and/or additional info.
1831
1832 const char* ErrorStr() const;
1833
1835 void PrintError() const;
1836
1838 int ErrorLineNum() const
1839 {
1840 return _errorLineNum;
1841 }
1842
1844 void Clear();
1845
1846// Copies this document to a target document.
1847// The target will be completely cleared before the copy.
1848// If you want to copy a sub-tree, see XMLNode::DeepClone().
1849//
1850// NOTE: that the 'target' must be non-null.
1851
1852 void DeepCopy(XMLDocument* target) const;
1853
1854 // internal
1855 char* Identify(char* p, XMLNode** node );
1856
1857 // internal
1858 void MarkInUse(XMLNode*);
1859
1860 virtual XMLNode* ShallowClone(XMLDocument*) const {
1861 return nullptr;
1862 }
1863 virtual bool ShallowEqual(const XMLNode*) const {
1864 return false;
1865 }
1866
1867private:
1868 XMLDocument(const XMLDocument&); // not supported
1869 void operator= (const XMLDocument&); // not supported
1870
1871 bool _writeBOM;
1872 bool _processEntities;
1873 XMLError _errorID;
1874 Whitespace _whitespaceMode;
1875 mutable StrPair _errorStr;
1876 int _errorLineNum;
1877 char* _charBuffer;
1878 int _parseCurLineNum;
1879 // Memory tracking does add some overhead.
1880 // However, the code assumes that you don't
1881 // have a bunch of unlinked nodes around.
1882 // Therefore it takes less memory to track
1883 // in the document vs. a linked list in the XMLNode,
1884 // and the performance is the same.
1885 DynArray<XMLNode*, 10> _unlinked;
1886
1887 MemPoolT< sizeof(XMLElement) > _elementPool;
1888 MemPoolT< sizeof(XMLAttribute) > _attributePool;
1889 MemPoolT< sizeof(XMLText) > _textPool;
1890 MemPoolT< sizeof(XMLComment) > _commentPool;
1891
1892 static const char* _errorNames[XML_ERROR_COUNT];
1893
1894 void Parse();
1895
1896 void SetError(XMLError error, int lineNum, const char* format, ...);
1897
1898 template<class NodeType, int PoolElementSize>
1899 NodeType* CreateUnlinkedNode(MemPoolT<PoolElementSize>& pool );
1900};
1901
1902template<class NodeType, int PoolElementSize>
1903inline NodeType* XMLDocument::CreateUnlinkedNode(MemPoolT<PoolElementSize>& pool )
1904{
1905 TIXMLASSERT(sizeof(NodeType ) == PoolElementSize );
1906 TIXMLASSERT(sizeof(NodeType ) == pool.ItemSize());
1907 NodeType* returnNode = new(pool.Alloc()) NodeType(this );
1908 TIXMLASSERT(returnNode );
1909 returnNode->_memPool = &pool;
1910
1911 _unlinked.Push(returnNode);
1912 return returnNode;
1913}
1914
1915
1916// A XMLHandle is a class that wraps a node pointer with null checks; this is
1917// an incredibly useful thing. Note that XMLHandle is not part of the TinyXML-2
1918// DOM structure. It is a separate utility class.
1919//
1920// Take an example:
1921// @verbatim
1922// <Document>
1923// <Element attributeA = "valueA">
1924// <Child attributeB = "value1" />
1925// <Child attributeB = "value2" />
1926// </Element>
1927// </Document>
1928// @endverbatim
1929//
1930// Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very
1931// easy to write a *lot* of code that looks like:
1932//
1933// @verbatim
1934// XMLElement* root = document.FirstChildElement("Document");
1935// if(root )
1936// {
1937// XMLElement* element = root->FirstChildElement("Element");
1938// if(element )
1939// {
1940// XMLElement* child = element->FirstChildElement("Child");
1941// if(child )
1942// {
1943// XMLElement* child2 = child->NextSiblingElement("Child");
1944// if(child2 )
1945// {
1946// // Finally do something useful.
1947// @endverbatim
1948//
1949// And that doesn't even cover "else" cases. XMLHandle addresses the verbosity
1950// of such code. A XMLHandle checks for null pointers so it is perfectly safe
1951// and correct to use:
1952//
1953// @verbatim
1954// XMLHandle docHandle(&document );
1955// XMLElement* child2 = docHandle.FirstChildElement("Document").FirstChildElement("Element").FirstChildElement().NextSiblingElement();
1956// if(child2 )
1957// {
1958// // do something useful
1959// @endverbatim
1960//
1961// Which is MUCH more concise and useful.
1962//
1963// It is also safe to copy handles - internally they are nothing more than node pointers.
1964// @verbatim
1965// XMLHandle handleCopy = handle;
1966// @endverbatim
1967//
1968// See also XMLConstHandle, which is the same as XMLHandle, but operates on const objects.
1969
1970class TINYXML2_LIB XMLHandle
1971{
1972public:
1974 XMLHandle(XMLNode* node ) : _node(node ) {
1975 }
1977 XMLHandle(XMLNode& node ) : _node(&node ) {
1978 }
1980 XMLHandle(const XMLHandle& ref ) : _node(ref._node ) {
1981 }
1983 XMLHandle& operator= (const XMLHandle& ref ) {
1984 _node = ref._node;
1985 return *this;
1986 }
1987
1990 return XMLHandle(_node ? _node->FirstChild() : nullptr );
1991 }
1993 XMLHandle FirstChildElement(const char* name = nullptr ) {
1994 return XMLHandle(_node ? _node->FirstChildElement(name ) : nullptr );
1995 }
1998 return XMLHandle(_node ? _node->LastChild() : nullptr );
1999 }
2001 XMLHandle LastChildElement(const char* name = nullptr ) {
2002 return XMLHandle(_node ? _node->LastChildElement(name ) : nullptr );
2003 }
2006 return XMLHandle(_node ? _node->PreviousSibling() : nullptr );
2007 }
2009 XMLHandle PreviousSiblingElement(const char* name = nullptr ) {
2010 return XMLHandle(_node ? _node->PreviousSiblingElement(name ) : nullptr );
2011 }
2014 return XMLHandle(_node ? _node->NextSibling() : nullptr );
2015 }
2017 XMLHandle NextSiblingElement(const char* name = nullptr ) {
2018 return XMLHandle(_node ? _node->NextSiblingElement(name ) : nullptr );
2019 }
2020
2023 return _node;
2024 }
2027 return(_node ? _node->ToElement() : nullptr );
2028 }
2031 return(_node ? _node->ToText() : nullptr );
2032 }
2035 return(_node ? _node->ToUnknown() : nullptr );
2036 }
2039 return(_node ? _node->ToDeclaration() : nullptr );
2040 }
2041
2042private:
2043 XMLNode* _node;
2044};
2045
2046// A variant of the XMLHandle class for working with const XMLNodes and Documents. It is the
2047// same in all regards, except for the 'const' qualifiers. See XMLHandle for API.
2048
2049class TINYXML2_LIB XMLConstHandle
2050{
2051public:
2052 XMLConstHandle(const XMLNode* node ) : _node(node ) {
2053 }
2054 XMLConstHandle(const XMLNode& node ) : _node(&node ) {
2055 }
2056 XMLConstHandle(const XMLConstHandle& ref ) : _node(ref._node ) {
2057 }
2058
2059 XMLConstHandle& operator= (const XMLConstHandle& ref ) {
2060 _node = ref._node;
2061 return *this;
2062 }
2063
2064 const XMLConstHandle FirstChild() const {
2065 return XMLConstHandle(_node ? _node->FirstChild() : nullptr );
2066 }
2067 const XMLConstHandle FirstChildElement(const char* name = nullptr ) const {
2068 return XMLConstHandle(_node ? _node->FirstChildElement(name ) : nullptr );
2069 }
2070 const XMLConstHandle LastChild() const {
2071 return XMLConstHandle(_node ? _node->LastChild() : nullptr );
2072 }
2073 const XMLConstHandle LastChildElement(const char* name = nullptr ) const {
2074 return XMLConstHandle(_node ? _node->LastChildElement(name ) : nullptr );
2075 }
2076 const XMLConstHandle PreviousSibling() const {
2077 return XMLConstHandle(_node ? _node->PreviousSibling() : nullptr );
2078 }
2079 const XMLConstHandle PreviousSiblingElement(const char* name = nullptr ) const {
2080 return XMLConstHandle(_node ? _node->PreviousSiblingElement(name ) : nullptr );
2081 }
2082 const XMLConstHandle NextSibling() const {
2083 return XMLConstHandle(_node ? _node->NextSibling() : nullptr );
2084 }
2085 const XMLConstHandle NextSiblingElement(const char* name = nullptr ) const {
2086 return XMLConstHandle(_node ? _node->NextSiblingElement(name ) : nullptr );
2087 }
2088
2089
2090 const XMLNode* ToNode() const {
2091 return _node;
2092 }
2093 const XMLElement* ToElement() const {
2094 return(_node ? _node->ToElement() : nullptr );
2095 }
2096 const XMLText* ToText() const {
2097 return(_node ? _node->ToText() : nullptr );
2098 }
2099 const XMLUnknown* ToUnknown() const {
2100 return(_node ? _node->ToUnknown() : nullptr );
2101 }
2102 const XMLDeclaration* ToDeclaration() const {
2103 return(_node ? _node->ToDeclaration() : nullptr );
2104 }
2105
2106private:
2107 const XMLNode* _node;
2108};
2109
2110
2111
2112// Printing functionality. The XMLPrinter gives you more
2113// options than the XMLDocument::Print() method.
2114//
2115// It can:
2116// -# Print to memory.
2117// -# Print to a file you provide.
2118// -# Print XML without a XMLDocument.
2119//
2120// Print to Memory
2121//
2122// @verbatim
2123// XMLPrinter printer;
2124// doc.Print(&printer );
2125// SomeFunction(printer.CStr());
2126// @endverbatim
2127//
2128// Print to a File
2129//
2130// You provide the file pointer.
2131// @verbatim
2132// XMLPrinter printer(fp );
2133// doc.Print(&printer );
2134// @endverbatim
2135//
2136// Print without a XMLDocument
2137//
2138// When loading, an XML parser is very useful. However, sometimes
2139// when saving, it just gets in the way. The code is often set up
2140// for streaming, and constructing the DOM is just overhead.
2141//
2142// The Printer supports the streaming case. The following code
2143// prints out a trivially simple XML file without ever creating
2144// an XML document.
2145//
2146// @verbatim
2147// XMLPrinter printer(fp );
2148// printer.OpenElement("foo");
2149// printer.PushAttribute("foo", "bar");
2150// printer.CloseElement();
2151// @endverbatim
2152
2153class TINYXML2_LIB XMLPrinter : public XMLVisitor
2154{
2155public:
2156// Construct the printer. If the FILE* is specified,
2157// this will print to the FILE. Else it will print
2158// to memory, and the result is available in CStr().
2159// If 'compact' is set to true, then output is created
2160// with only required whitespace and newlines.
2161
2162 XMLPrinter(FILE* file=nullptr, bool compact = false, int depth = 0 );
2163 virtual ~XMLPrinter() {}
2164
2165// If streaming, write the BOM and declaration.
2166 void PushHeader(bool writeBOM, bool writeDeclaration );
2167// If streaming, start writing an element.
2168// The element must be closed with CloseElement()
2169
2170 void OpenElement(const char* name, bool compactMode=false );
2172 void PushAttribute(const char* name, const char* value );
2173 void PushAttribute(const char* name, int value );
2174 void PushAttribute(const char* name, unsigned value );
2175 void PushAttribute(const char* name, int64_t value);
2176 void PushAttribute(const char* name, bool value );
2177 void PushAttribute(const char* name, double value );
2179 virtual void CloseElement(bool compactMode=false );
2180
2182 void PushText(const char* text, bool cdata=false );
2184 void PushText(int value );
2186 void PushText(unsigned value );
2188 void PushText(int64_t value);
2190 void PushText(bool value );
2192 void PushText(float value );
2194 void PushText(double value );
2195
2197 void PushComment(const char* comment );
2198
2199 void PushDeclaration(const char* value );
2200 void PushUnknown(const char* value );
2201
2202 virtual bool VisitEnter(const XMLDocument&);
2203 virtual bool VisitExit(const XMLDocument&) {
2204 return true;
2205 }
2206
2207 virtual bool VisitEnter(const XMLElement& element, const XMLAttribute* attribute );
2208 virtual bool VisitExit(const XMLElement& element );
2209
2210 virtual bool Visit(const XMLText& text );
2211 virtual bool Visit(const XMLComment& comment );
2212 virtual bool Visit(const XMLDeclaration& declaration );
2213 virtual bool Visit(const XMLUnknown& unknown );
2214
2215
2216// If in print to memory mode, return a pointer to
2217// the XML file in memory.
2218
2219 const char* CStr() const {
2220 return _buffer.Mem();
2221 }
2222
2223// If in print to memory mode, return the size
2224// of the XML file in memory.(Note the size returned
2225// includes the terminating null.)
2226
2227 int CStrSize() const {
2228 return _buffer.Size();
2229 }
2230
2231// If in print to memory mode, reset the buffer to the
2232// beginning.
2233
2234 void ClearBuffer() {
2235 _buffer.Clear();
2236 _buffer.Push(0);
2237 _firstElement = true;
2238 }
2239
2240protected:
2241 virtual bool CompactMode(const XMLElement&) { return _compactMode; }
2242
2243// Prints out the space before an element. You may override to change
2244// the space and tabs used. A PrintSpace() override should call Print().
2245
2246 virtual void PrintSpace(int depth );
2247 void Print(const char* format, ...);
2248 void Write(const char* data, int size );
2249 inline void Write(const char* data ) { Write(data, static_cast<int>(strlen(data))); }
2250 void Putc(char ch );
2251
2252 void SealElementIfJustOpened();
2253 bool _elementJustOpened;
2254 DynArray< const char*, 10 > _stack;
2255
2256private:
2257 void PrintString(const char*, bool restrictedEntitySet ); // prints out, after detecting entities.
2258
2259 bool _firstElement;
2260 FILE* _fp;
2261 int _depth;
2262 int _textDepth;
2263 bool _processEntities;
2264 bool _compactMode;
2265
2266 enum {
2267 ENTITY_RANGE = 64,
2268 BUF_SIZE = 200
2269 };
2270 bool _entityFlag[ENTITY_RANGE];
2271 bool _restrictedEntityFlag[ENTITY_RANGE];
2272
2273 DynArray< char, 20 > _buffer;
2274
2275 // Prohibit cloning, intentionally not implemented
2276 XMLPrinter(const XMLPrinter&);
2277 XMLPrinter& operator= (const XMLPrinter&);
2278};
2279
2280
2281} // tinyxml2
2282
2283#if defined(_MSC_VER)
2284# pragma warning(pop)
2285#endif
2286
2287#endif // TINYXML2_INCLUDED
const XMLAttribute * Next() const
The next attribute in the list.
Definition: tinyxml2.h:1142
double DoubleValue() const
Query as a double. See IntValue()
Definition: tinyxml2.h:1175
XMLError QueryUnsignedValue(unsigned int *value) const
See QueryIntValue.
Definition: tinyxml2.cpp:1526
XMLError QueryBoolValue(bool *value) const
See QueryIntValue.
Definition: tinyxml2.cpp:1546
XMLError QueryFloatValue(float *value) const
See QueryIntValue.
Definition: tinyxml2.cpp:1556
float FloatValue() const
Query as a float. See IntValue()
Definition: tinyxml2.h:1181
unsigned UnsignedValue() const
Query as an unsigned integer. See IntValue()
Definition: tinyxml2.h:1163
void SetAttribute(const char *value)
Set the attribute to a string value.
Definition: tinyxml2.cpp:1576
XMLError QueryDoubleValue(double *value) const
See QueryIntValue.
Definition: tinyxml2.cpp:1566
bool BoolValue() const
Query as a boolean. See IntValue()
Definition: tinyxml2.h:1169
const char * Value() const
The value of the attribute.
Definition: tinyxml2.cpp:1474
int GetLineNum() const
Gets the line number the attribute is in, if the document was parsed from a file.
Definition: tinyxml2.h:1139
XMLError QueryInt64Value(int64_t *value) const
See QueryIntValue.
Definition: tinyxml2.cpp:1536
virtual XMLComment * ToComment()
Safely cast to a Comment, or null.
Definition: tinyxml2.h:1023
virtual XMLDeclaration * ToDeclaration()
Safely cast to a Declaration, or null.
Definition: tinyxml2.h:1062
virtual XMLDocument * ToDocument()
Safely cast to a Document, or null.
Definition: tinyxml2.h:1667
XMLError ErrorID() const
Return the errorID.
Definition: tinyxml2.h:1823
bool Error() const
Return true if there was an error parsing the document.
Definition: tinyxml2.h:1819
int ErrorLineNum() const
Return the line where the error occured, or zero if unknown.
Definition: tinyxml2.h:1838
XMLError QueryDoubleAttribute(const char *name, double *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1354
void SetAttribute(const char *name, const char *value)
Sets the named attribute to value.
Definition: tinyxml2.h:1424
void SetAttribute(const char *name, bool value)
Sets the named attribute to value.
Definition: tinyxml2.h:1446
void SetAttribute(const char *name, int64_t value)
Sets the named attribute to value.
Definition: tinyxml2.h:1440
const XMLAttribute * FirstAttribute() const
Return the first attribute in the list.
Definition: tinyxml2.h:1467
const char * Name() const
Get the name of an element(which is the Value() of the node.)
Definition: tinyxml2.h:1247
void SetAttribute(const char *name, double value)
Sets the named attribute to value.
Definition: tinyxml2.h:1451
void SetAttribute(const char *name, float value)
Sets the named attribute to value.
Definition: tinyxml2.h:1456
XMLError QueryBoolAttribute(const char *name, bool *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1346
void SetName(const char *str, bool staticMem=false)
Set the name of the element.
Definition: tinyxml2.h:1251
XMLError QueryInt64Attribute(const char *name, int64_t *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1337
virtual XMLElement * ToElement()
Safely cast to an Element, or null.
Definition: tinyxml2.h:1255
XMLError QueryStringAttribute(const char *name, const char **value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1371
void SetAttribute(const char *name, int value)
Sets the named attribute to value.
Definition: tinyxml2.h:1429
void SetAttribute(const char *name, unsigned value)
Sets the named attribute to value.
Definition: tinyxml2.h:1434
XMLError QueryUnsignedAttribute(const char *name, unsigned int *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1328
XMLError QueryFloatAttribute(const char *name, float *value) const
See QueryIntAttribute()
Definition: tinyxml2.h:1362
XMLHandle NextSibling()
Get the next sibling of this handle.
Definition: tinyxml2.h:2013
XMLUnknown * ToUnknown()
Safe cast to XMLUnknown. This can return null.
Definition: tinyxml2.h:2034
XMLHandle PreviousSibling()
Get the previous sibling of this handle.
Definition: tinyxml2.h:2005
XMLNode * ToNode()
Safe cast to XMLNode. This can return null.
Definition: tinyxml2.h:2022
XMLHandle PreviousSiblingElement(const char *name=nullptr)
Get the previous sibling element of this handle.
Definition: tinyxml2.h:2009
XMLElement * ToElement()
Safe cast to XMLElement. This can return null.
Definition: tinyxml2.h:2026
XMLHandle LastChild()
Get the last child of this handle.
Definition: tinyxml2.h:1997
XMLHandle(XMLNode *node)
Create a handle from any node(at any depth of the tree.) This can be a null pointer.
Definition: tinyxml2.h:1974
XMLHandle(const XMLHandle &ref)
Copy constructor.
Definition: tinyxml2.h:1980
XMLDeclaration * ToDeclaration()
Safe cast to XMLDeclaration. This can return null.
Definition: tinyxml2.h:2038
XMLText * ToText()
Safe cast to XMLText. This can return null.
Definition: tinyxml2.h:2030
XMLHandle FirstChildElement(const char *name=nullptr)
Get the first child element of this handle.
Definition: tinyxml2.h:1993
XMLHandle NextSiblingElement(const char *name=nullptr)
Get the next sibling element of this handle.
Definition: tinyxml2.h:2017
XMLHandle(XMLNode &node)
Create a handle from a node.
Definition: tinyxml2.h:1977
XMLHandle FirstChild()
Get the first child of this handle.
Definition: tinyxml2.h:1989
XMLHandle LastChildElement(const char *name=nullptr)
Get the last child element of this handle.
Definition: tinyxml2.h:2001
virtual XMLDeclaration * ToDeclaration()
Safely cast to a Declaration, or null.
Definition: tinyxml2.h:696
bool NoChildren() const
Returns true if this node has no children.
Definition: tinyxml2.h:752
virtual XMLDocument * ToDocument()
Safely cast to a Document, or null.
Definition: tinyxml2.h:692
virtual XMLText * ToText()
Safely cast to Text, or null.
Definition: tinyxml2.h:684
virtual XMLUnknown * ToUnknown()
Safely cast to an Unknown, or null.
Definition: tinyxml2.h:700
const XMLNode * NextSibling() const
Get the next(right) sibling node of this node.
Definition: tinyxml2.h:809
XMLDocument * GetDocument()
Get the XMLDocument that owns this XMLNode.
Definition: tinyxml2.h:674
const XMLDocument * GetDocument() const
Get the XMLDocument that owns this XMLNode.
Definition: tinyxml2.h:669
const XMLNode * LastChild() const
Get the last child node, or null if none exists.
Definition: tinyxml2.h:775
const XMLNode * Parent() const
Get the parent of this node on the DOM.
Definition: tinyxml2.h:743
const XMLNode * PreviousSibling() const
Get the previous(left) sibling node of this node.
Definition: tinyxml2.h:793
int GetLineNum() const
Gets the line number the node is in, if the document was parsed from a file.
Definition: tinyxml2.h:740
const XMLNode * FirstChild() const
Get the first child node, or null if none exists.
Definition: tinyxml2.h:757
virtual XMLElement * ToElement()
Safely cast to an Element, or null.
Definition: tinyxml2.h:680
virtual XMLComment * ToComment()
Safely cast to a Comment, or null.
Definition: tinyxml2.h:688
virtual bool VisitExit(const XMLDocument &)
Visit a document.
Definition: tinyxml2.h:2203
virtual XMLText * ToText()
Safely cast to Text, or null.
Definition: tinyxml2.h:985
bool CData() const
Returns true if this is a CDATA text element.
Definition: tinyxml2.h:997
void SetCData(bool isCData)
Declare whether this should be CDATA or standard text.
Definition: tinyxml2.h:993
virtual XMLUnknown * ToUnknown()
Safely cast to an Unknown, or null.
Definition: tinyxml2.h:1097
virtual bool Visit(const XMLUnknown &)
Visit an unknown node.
Definition: tinyxml2.h:510
virtual bool VisitEnter(const XMLDocument &)
Visit a document.
Definition: tinyxml2.h:480
virtual bool Visit(const XMLDeclaration &)
Visit a declaration.
Definition: tinyxml2.h:498
virtual bool VisitExit(const XMLDocument &)
Visit a document.
Definition: tinyxml2.h:484
virtual bool VisitExit(const XMLElement &)
Visit an element.
Definition: tinyxml2.h:493
virtual bool VisitEnter(const XMLElement &, const XMLAttribute *)
Visit an element.
Definition: tinyxml2.h:489
virtual bool Visit(const XMLComment &)
Visit a comment node.
Definition: tinyxml2.h:506
virtual bool Visit(const XMLText &)
Visit a text node.
Definition: tinyxml2.h:502