1c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie/* 2c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieOriginal code by Lee Thomason (www.grinninglizard.com) 3c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 4c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieThis software is provided 'as-is', without any express or implied 5c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiewarranty. In no event will the authors be held liable for any 6c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiedamages arising from the use of this software. 7c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 8c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XiePermission is granted to anyone to use this software for any 9c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiepurpose, including commercial applications, and to alter it and 10c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieredistribute it freely, subject to the following restrictions: 11c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 12c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie1. The origin of this software must not be misrepresented; you must 13c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xienot claim that you wrote the original software. If you use this 14c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiesoftware in a product, an acknowledgment in the product documentation 15c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiewould be appreciated but is not required. 16c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 17c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie2. Altered source versions must be plainly marked as such, and 18c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiemust not be misrepresented as being the original software. 19c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 20c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie3. This notice may not be removed or altered from any source 21c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiedistribution. 22c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie*/ 23c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 24c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#ifndef TINYXML2_INCLUDED 25c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#define TINYXML2_INCLUDED 26c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 27c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#include <cctype> 28c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#include <climits> 29c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#include <cstdio> 30c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#include <cstring> 31c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie//#include <cstdarg> 32c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#include <stdarg.h> 33c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie/* 34c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie TODO: intern strings instead of allocation. 35c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie*/ 36c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie/* 37c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie gcc: g++ -Wall tinyxml2.cpp xmltest.cpp -o gccxmltest.exe 38c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie*/ 39c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 40c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#if defined( _DEBUG ) || defined( DEBUG ) || defined (__DEBUG__) 41c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie #ifndef DEBUG 42c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie #define DEBUG 43c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie #endif 44c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#endif 45c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 46c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 47c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#if defined(DEBUG) 48c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie #if defined(_MSC_VER) 49c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie #define TIXMLASSERT( x ) if ( !(x)) { __debugbreak(); } //if ( !(x)) WinDebugBreak() 50c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie #elif defined (ANDROID_NDK) 51c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie #include <android/log.h> 52c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie #define TIXMLASSERT( x ) if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); } 53c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie #else 54c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie #include <assert.h> 55c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie #define TIXMLASSERT assert 56c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie #endif 57c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#else 58c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie #define TIXMLASSERT( x ) {} 59c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#endif 60c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 61c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 62c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) 63c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // Microsoft visual studio, version 2005 and higher. 64c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /*int _snprintf_s( 65c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char *buffer, 66c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie size_t sizeOfBuffer, 67c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie size_t count, 68c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const char *format [, 69c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie argument] ... 70c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie );*/ 71c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie inline int TIXML_SNPRINTF( char* buffer, size_t size, const char* format, ... ) { 72c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie va_list va; 73c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie va_start( va, format ); 74c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int result = vsnprintf_s( buffer, size, _TRUNCATE, format, va ); 75c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie va_end( va ); 76c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return result; 77c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 78c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie #define TIXML_SSCANF sscanf_s 79c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#else 80c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // GCC version 3 and higher 81c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie //#warning( "Using sn* functions." ) 82c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie #define TIXML_SNPRINTF snprintf 83c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie #define TIXML_SSCANF sscanf 84c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#endif 85c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 86c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiestatic const int TIXML2_MAJOR_VERSION = 1; 87c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiestatic const int TIXML2_MINOR_VERSION = 0; 88c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiestatic const int TIXML2_PATCH_VERSION = 6; 89c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 90c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xienamespace tinyxml2 91c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 92c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieclass XMLDocument; 93c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieclass XMLElement; 94c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieclass XMLAttribute; 95c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieclass XMLComment; 96c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieclass XMLNode; 97c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieclass XMLText; 98c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieclass XMLDeclaration; 99c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieclass XMLUnknown; 100c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 101c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieclass XMLPrinter; 102c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 103c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie/* 104c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie A class that wraps strings. Normally stores the start and end 105c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie pointers into the XML file itself, and will apply normalization 106c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie and entity translation if actually read. Can also store (and memory 107c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie manage) a traditional char[] 108c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie*/ 109c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieclass StrPair 110c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 111c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiepublic: 112c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie enum { 113c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie NEEDS_ENTITY_PROCESSING = 0x01, 114c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie NEEDS_NEWLINE_NORMALIZATION = 0x02, 115c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 116c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION, 117c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie TEXT_ELEMENT_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION, 118c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ATTRIBUTE_NAME = 0, 119c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION, 120c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION, 121c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie COMMENT = NEEDS_NEWLINE_NORMALIZATION 122c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie }; 123c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 124c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie StrPair() : flags( 0 ), start( 0 ), end( 0 ) {} 125c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ~StrPair(); 126c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 127c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void Set( char* _start, char* _end, int _flags ) { 128c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Reset(); 129c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie this->start = _start; this->end = _end; this->flags = _flags | NEEDS_FLUSH; 130c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 131c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const char* GetStr(); 132c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie bool Empty() const { return start == end; } 133c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 134c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void SetInternedStr( const char* str ) { Reset(); this->start = const_cast<char*>(str); } 135c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void SetStr( const char* str, int flags=0 ); 136c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 137c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char* ParseText( char* in, const char* endTag, int strFlags ); 138c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char* ParseName( char* in ); 139c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 140c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 141c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieprivate: 142c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void Reset(); 143c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 144c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie enum { 145c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie NEEDS_FLUSH = 0x100, 146c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie NEEDS_DELETE = 0x200 147c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie }; 148c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 149c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // After parsing, if *end != 0, it can be set to zero. 150c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int flags; 151c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char* start; 152c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char* end; 153c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie}; 154c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 155c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 156c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie/* 157c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie A dynamic array of Plain Old Data. Doesn't support constructors, etc. 158c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Has a small initial memory pool, so that low or no usage will not 159c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie cause a call to new/delete 160c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie*/ 161c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xietemplate <class T, int INIT> 162c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieclass DynArray 163c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 164c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiepublic: 165c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie DynArray< T, INIT >() 166c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { 167c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie mem = pool; 168c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie allocated = INIT; 169c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie size = 0; 170c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 171c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ~DynArray() 172c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { 173c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( mem != pool ) { 174c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie delete [] mem; 175c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 176c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 177c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void Push( T t ) 178c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { 179c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie EnsureCapacity( size+1 ); 180c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie mem[size++] = t; 181c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 182c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 183c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie T* PushArr( int count ) 184c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { 185c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie EnsureCapacity( size+count ); 186c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie T* ret = &mem[size]; 187c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie size += count; 188c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return ret; 189c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 190c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie T Pop() { 191c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return mem[--size]; 192c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 193c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void PopArr( int count ) 194c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { 195c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie TIXMLASSERT( size >= count ); 196c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie size -= count; 197c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 198c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 199c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie bool Empty() const { return size == 0; } 200c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie T& operator[](int i) { TIXMLASSERT( i>= 0 && i < size ); return mem[i]; } 201c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const T& operator[](int i) const { TIXMLASSERT( i>= 0 && i < size ); return mem[i]; } 202c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int Size() const { return size; } 203c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int Capacity() const { return allocated; } 204c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const T* Mem() const { return mem; } 205c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie T* Mem() { return mem; } 206c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 207c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 208c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieprivate: 209c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void EnsureCapacity( int cap ) { 210c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( cap > allocated ) { 211c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int newAllocated = cap * 2; 212c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie T* newMem = new T[newAllocated]; 213c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie memcpy( newMem, mem, sizeof(T)*size ); // warning: not using constructors, only works for PODs 214c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( mem != pool ) delete [] mem; 215c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie mem = newMem; 216c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie allocated = newAllocated; 217c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 218c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 219c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 220c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie T* mem; 221c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie T pool[INIT]; 222c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int allocated; // objects allocated 223c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int size; // number objects in use 224c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie}; 225c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 226c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 227c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie/* 228c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Parent virtual class of a pool for fast allocation 229c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie and deallocation of objects. 230c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie*/ 231c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieclass MemPool 232c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 233c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiepublic: 234c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie MemPool() {} 235c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual ~MemPool() {} 236c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 237c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual int ItemSize() const = 0; 238c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual void* Alloc() = 0; 239c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual void Free( void* ) = 0; 240c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie}; 241c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 242c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 243c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie/* 244c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Template child class to create pools of the correct type. 245c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie*/ 246c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xietemplate< int SIZE > 247c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieclass MemPoolT : public MemPool 248c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 249c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiepublic: 250c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie MemPoolT() : root(0), currentAllocs(0), nAllocs(0), maxAllocs(0) {} 251c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ~MemPoolT() { 252c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // Delete the blocks. 253c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie for( int i=0; i<blockPtrs.Size(); ++i ) { 254c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie delete blockPtrs[i]; 255c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 256c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 257c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 258c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual int ItemSize() const { return SIZE; } 259c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int CurrentAllocs() const { return currentAllocs; } 260c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 261c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual void* Alloc() { 262c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !root ) { 263c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // Need a new block. 264c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Block* block = new Block(); 265c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie blockPtrs.Push( block ); 266c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 267c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie for( int i=0; i<COUNT-1; ++i ) { 268c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie block->chunk[i].next = &block->chunk[i+1]; 269c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 270c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie block->chunk[COUNT-1].next = 0; 271c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie root = block->chunk; 272c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 273c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void* result = root; 274c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie root = root->next; 275c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 276c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ++currentAllocs; 277c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( currentAllocs > maxAllocs ) maxAllocs = currentAllocs; 278c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie nAllocs++; 279c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return result; 280c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 281c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual void Free( void* mem ) { 282c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !mem ) return; 283c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie --currentAllocs; 284c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Chunk* chunk = (Chunk*)mem; 285c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie memset( chunk, 0xfe, sizeof(Chunk) ); 286c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie chunk->next = root; 287c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie root = chunk; 288c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 289c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void Trace( const char* name ) { 290c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n", 291c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie name, maxAllocs, maxAllocs*SIZE/1024, currentAllocs, SIZE, nAllocs, blockPtrs.Size() ); 292c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 293c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 294c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieprivate: 295c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie enum { COUNT = 1024/SIZE }; 296c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie union Chunk { 297c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Chunk* next; 298c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char mem[SIZE]; 299c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie }; 300c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie struct Block { 301c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Chunk chunk[COUNT]; 302c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie }; 303c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie DynArray< Block*, 10 > blockPtrs; 304c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Chunk* root; 305c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 306c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int currentAllocs; 307c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int nAllocs; 308c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int maxAllocs; 309c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie}; 310c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 311c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 312c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 313c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie/** 314c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Implements the interface to the "Visitor pattern" (see the Accept() method.) 315c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie If you call the Accept() method, it requires being passed a XMLVisitor 316c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie class to handle callbacks. For nodes that contain other nodes (Document, Element) 317c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie you will get called with a VisitEnter/VisitExit pair. Nodes that are always leafs 318c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie are simply called with Visit(). 319c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 320c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie If you return 'true' from a Visit method, recursive parsing will continue. If you return 321c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie false, <b>no children of this node or its sibilings</b> will be visited. 322c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 323c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie All flavors of Visit methods have a default implementation that returns 'true' (continue 324c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie visiting). You need to only override methods that are interesting to you. 325c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 326c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Generally Accept() is called on the TiXmlDocument, although all nodes support visiting. 327c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 328c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie You should never change the document from a callback. 329c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 330c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @sa XMLNode::Accept() 331c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie*/ 332c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieclass XMLVisitor 333c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 334c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiepublic: 335c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual ~XMLVisitor() {} 336c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 337c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Visit a document. 338c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual bool VisitEnter( const XMLDocument& /*doc*/ ) { return true; } 339c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Visit a document. 340c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual bool VisitExit( const XMLDocument& /*doc*/ ) { return true; } 341c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 342c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Visit an element. 343c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual bool VisitEnter( const XMLElement& /*element*/, const XMLAttribute* /*firstAttribute*/ ) { return true; } 344c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Visit an element. 345c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual bool VisitExit( const XMLElement& /*element*/ ) { return true; } 346c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 347c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Visit a declaration. 348c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual bool Visit( const XMLDeclaration& /*declaration*/ ) { return true; } 349c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Visit a text node. 350c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual bool Visit( const XMLText& /*text*/ ) { return true; } 351c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Visit a comment node. 352c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual bool Visit( const XMLComment& /*comment*/ ) { return true; } 353c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Visit an unknown node. 354c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual bool Visit( const XMLUnknown& /*unknown*/ ) { return true; } 355c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie}; 356c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 357c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 358c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie/* 359c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Utility functionality. 360c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie*/ 361c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieclass XMLUtil 362c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 363c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiepublic: 364c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't 365c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // correct, but simple, and usually works. 366c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie static const char* SkipWhiteSpace( const char* p ) { while( !IsUTF8Continuation(*p) && isspace( *reinterpret_cast<const unsigned char*>(p) ) ) { ++p; } return p; } 367c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie static char* SkipWhiteSpace( char* p ) { while( !IsUTF8Continuation(*p) && isspace( *reinterpret_cast<unsigned char*>(p) ) ) { ++p; } return p; } 368c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 369c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX ) { 370c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int n = 0; 371c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( p == q ) { 372c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return true; 373c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 374c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie while( *p && *q && *p == *q && n<nChar ) { 375c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ++p; ++q; ++n; 376c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 377c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( (n == nChar) || ( *p == 0 && *q == 0 ) ) { 378c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return true; 379c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 380c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return false; 381c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 382c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie inline static int IsUTF8Continuation( const char p ) { return p & 0x80; } 383c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie inline static int IsAlphaNum( unsigned char anyByte ) { return ( anyByte < 128 ) ? isalnum( anyByte ) : 1; } 384c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie inline static int IsAlpha( unsigned char anyByte ) { return ( anyByte < 128 ) ? isalpha( anyByte ) : 1; } 385c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 386c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie static const char* ReadBOM( const char* p, bool* hasBOM ); 387c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // p is the starting location, 388c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // the UTF-8 value of the entity will be placed in value, and length filled in. 389c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie static const char* GetCharacterRef( const char* p, char* value, int* length ); 390c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ); 391c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 392c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // converts primitive types to strings 393c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie static void ToStr( int v, char* buffer, int bufferSize ); 394c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie static void ToStr( unsigned v, char* buffer, int bufferSize ); 395c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie static void ToStr( bool v, char* buffer, int bufferSize ); 396c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie static void ToStr( float v, char* buffer, int bufferSize ); 397c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie static void ToStr( double v, char* buffer, int bufferSize ); 398c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 399c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // converts strings to primitive types 400c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie static bool ToInt( const char* str, int* value ); 401c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie static bool ToUnsigned( const char* str, unsigned* value ); 402c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie static bool ToBool( const char* str, bool* value ); 403c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie static bool ToFloat( const char* str, float* value ); 404c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie static bool ToDouble( const char* str, double* value ); 405c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie}; 406c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 407c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 408c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie/** XMLNode is a base class for every object that is in the 409c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XML Document Object Model (DOM), except XMLAttributes. 410c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Nodes have siblings, a parent, and children which can 411c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie be navigated. A node is always in a XMLDocument. 412c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie The type of a XMLNode can be queried, and it can 413c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie be cast to its more defined type. 414c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 415c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie A XMLDocument allocates memory for all its Nodes. 416c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie When the XMLDocument gets deleted, all its Nodes 417c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie will also be deleted. 418c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 419c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @verbatim 420c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie A Document can contain: Element (container or leaf) 421c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Comment (leaf) 422c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Unknown (leaf) 423c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Declaration( leaf ) 424c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 425c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie An Element can contain: Element (container or leaf) 426c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Text (leaf) 427c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Attributes (not on tree) 428c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Comment (leaf) 429c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Unknown (leaf) 430c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 431c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @endverbatim 432c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie*/ 433c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieclass XMLNode 434c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 435c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie friend class XMLDocument; 436c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie friend class XMLElement; 437c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiepublic: 438c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 439c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Get the XMLDocument that owns this XMLNode. 440c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLDocument* GetDocument() const { return document; } 441c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Get the XMLDocument that owns this XMLNode. 442c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLDocument* GetDocument() { return document; } 443c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 444c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual XMLElement* ToElement() { return 0; } ///< Safely cast to an Element, or null. 445c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual XMLText* ToText() { return 0; } ///< Safely cast to Text, or null. 446c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual XMLComment* ToComment() { return 0; } ///< Safely cast to a Comment, or null. 447c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual XMLDocument* ToDocument() { return 0; } ///< Safely cast to a Document, or null. 448c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual XMLDeclaration* ToDeclaration() { return 0; } ///< Safely cast to a Declaration, or null. 449c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual XMLUnknown* ToUnknown() { return 0; } ///< Safely cast to an Unknown, or null. 450c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 451c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual const XMLElement* ToElement() const { return 0; } 452c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual const XMLText* ToText() const { return 0; } 453c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual const XMLComment* ToComment() const { return 0; } 454c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual const XMLDocument* ToDocument() const { return 0; } 455c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual const XMLDeclaration* ToDeclaration() const { return 0; } 456c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual const XMLUnknown* ToUnknown() const { return 0; } 457c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 458c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** The meaning of 'value' changes for the specific type. 459c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @verbatim 460c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Document: empty 461c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Element: name of the element 462c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Comment: the comment text 463c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Unknown: the tag contents 464c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Text: the text string 465c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @endverbatim 466c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 467c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const char* Value() const { return value.GetStr(); } 468c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** Set the Value of an XML node. 469c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @sa Value() 470c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 471c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void SetValue( const char* val, bool staticMem=false ); 472c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 473c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Get the parent of this node on the DOM. 474c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLNode* Parent() const { return parent; } 475c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLNode* Parent() { return parent; } 476c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 477c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Returns true if this node has no children. 478c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie bool NoChildren() const { return !firstChild; } 479c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 480c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Get the first child node, or null if none exists. 481c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLNode* FirstChild() const { return firstChild; } 482c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLNode* FirstChild() { return firstChild; } 483c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** Get the first child element, or optionally the first child 484c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie element with the specified name. 485c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 486c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLElement* FirstChildElement( const char* value=0 ) const; 487c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLElement* FirstChildElement( const char* _value=0 ) { return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->FirstChildElement( _value )); } 488c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 489c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Get the last child node, or null if none exists. 490c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLNode* LastChild() const { return lastChild; } 491c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLNode* LastChild() { return const_cast<XMLNode*>(const_cast<const XMLNode*>(this)->LastChild() ); } 492c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 493c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** Get the last child element or optionally the last child 494c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie element with the specified name. 495c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 496c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLElement* LastChildElement( const char* value=0 ) const; 497c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLElement* LastChildElement( const char* _value=0 ) { return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->LastChildElement(_value) ); } 498c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 499c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Get the previous (left) sibling node of this node. 500c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLNode* PreviousSibling() const { return prev; } 501c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLNode* PreviousSibling() { return prev; } 502c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 503c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Get the previous (left) sibling element of this node, with an opitionally supplied name. 504c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLElement* PreviousSiblingElement( const char* value=0 ) const ; 505c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLElement* PreviousSiblingElement( const char* _value=0 ) { return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->PreviousSiblingElement( _value ) ); } 506c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 507c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Get the next (right) sibling node of this node. 508c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLNode* NextSibling() const { return next; } 509c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLNode* NextSibling() { return next; } 510c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 511c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Get the next (right) sibling element of this node, with an opitionally supplied name. 512c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLElement* NextSiblingElement( const char* value=0 ) const; 513c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLElement* NextSiblingElement( const char* _value=0 ) { return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->NextSiblingElement( _value ) ); } 514c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 515c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** 516c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Add a child node as the last (right) child. 517c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 518c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLNode* InsertEndChild( XMLNode* addThis ); 519c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 520c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLNode* LinkEndChild( XMLNode* addThis ) { return InsertEndChild( addThis ); } 521c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** 522c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Add a child node as the first (left) child. 523c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 524c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLNode* InsertFirstChild( XMLNode* addThis ); 525c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** 526c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Add a node after the specified child node. 527c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 528c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis ); 529c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 530c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** 531c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Delete all the children of this node. 532c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 533c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void DeleteChildren(); 534c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 535c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** 536c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Delete a child of this node. 537c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 538c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void DeleteChild( XMLNode* node ); 539c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 540c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** 541c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Make a copy of this node, but not its children. 542c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie You may pass in a Document pointer that will be 543c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie the owner of the new Node. If the 'document' is 544c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie null, then the node returned will be allocated 545c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie from the current Document. (this->GetDocument()) 546c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 547c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Note: if called on a XMLDocument, this will return null. 548c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 549c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0; 550c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 551c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** 552c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Test if 2 nodes are the same, but don't test children. 553c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie The 2 nodes do not need to be in the same Document. 554c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 555c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Note: if called on a XMLDocument, this will return false. 556c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 557c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual bool ShallowEqual( const XMLNode* compare ) const = 0; 558c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 559c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** Accept a hierarchical visit of the nodes in the TinyXML DOM. Every node in the 560c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XML tree will be conditionally visited and the host will be called back 561c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie via the TiXmlVisitor interface. 562c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 563c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse 564c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie the XML for the callbacks, so the performance of TinyXML is unchanged by using this 565c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie interface versus any other.) 566c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 567c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie The interface has been based on ideas from: 568c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 569c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie - http://www.saxproject.org/ 570c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie - http://c2.com/cgi/wiki?HierarchicalVisitorPattern 571c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 572c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Which are both good references for "visiting". 573c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 574c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie An example of using Accept(): 575c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @verbatim 576c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie TiXmlPrinter printer; 577c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie tinyxmlDoc.Accept( &printer ); 578c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const char* xmlcstr = printer.CStr(); 579c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @endverbatim 580c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 581c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual bool Accept( XMLVisitor* visitor ) const = 0; 582c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 583c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // internal 584c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual char* ParseDeep( char*, StrPair* ); 585c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 586c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieprotected: 587c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLNode( XMLDocument* ); 588c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual ~XMLNode(); 589c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLNode( const XMLNode& ); // not supported 590c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLNode& operator=( const XMLNode& ); // not supported 591c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 592c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLDocument* document; 593c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLNode* parent; 594c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie mutable StrPair value; 595c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 596c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLNode* firstChild; 597c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLNode* lastChild; 598c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 599c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLNode* prev; 600c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLNode* next; 601c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 602c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieprivate: 603c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie MemPool* memPool; 604c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void Unlink( XMLNode* child ); 605c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie}; 606c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 607c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 608c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie/** XML text. 609c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 610c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Note that a text node can have child element nodes, for example: 611c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @verbatim 612c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie <root>This is <b>bold</b></root> 613c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @endverbatim 614c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 615c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie A text node can have 2 ways to output the next. "normal" output 616c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie and CDATA. It will default to the mode it was parsed from the XML file and 617c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie you generally want to leave it alone, but you can change the output mode with 618c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie SetCDATA() and query it with CDATA(). 619c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie*/ 620c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieclass XMLText : public XMLNode 621c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 622c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie friend class XMLBase; 623c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie friend class XMLDocument; 624c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiepublic: 625c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual bool Accept( XMLVisitor* visitor ) const; 626c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 627c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual XMLText* ToText() { return this; } 628c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual const XMLText* ToText() const { return this; } 629c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 630c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Declare whether this should be CDATA or standard text. 631c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void SetCData( bool _isCData ) { this->isCData = _isCData; } 632c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Returns true if this is a CDATA text element. 633c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie bool CData() const { return isCData; } 634c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 635c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char* ParseDeep( char*, StrPair* endTag ); 636c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual XMLNode* ShallowClone( XMLDocument* document ) const; 637c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual bool ShallowEqual( const XMLNode* compare ) const; 638c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 639c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 640c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieprotected: 641c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLText( XMLDocument* doc ) : XMLNode( doc ), isCData( false ) {} 642c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual ~XMLText() {} 643c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLText( const XMLText& ); // not supported 644c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLText& operator=( const XMLText& ); // not supported 645c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 646c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieprivate: 647c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie bool isCData; 648c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie}; 649c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 650c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 651c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie/** An XML Comment. */ 652c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieclass XMLComment : public XMLNode 653c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 654c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie friend class XMLDocument; 655c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiepublic: 656c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual XMLComment* ToComment() { return this; } 657c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual const XMLComment* ToComment() const { return this; } 658c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 659c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual bool Accept( XMLVisitor* visitor ) const; 660c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 661c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char* ParseDeep( char*, StrPair* endTag ); 662c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual XMLNode* ShallowClone( XMLDocument* document ) const; 663c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual bool ShallowEqual( const XMLNode* compare ) const; 664c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 665c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieprotected: 666c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLComment( XMLDocument* doc ); 667c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual ~XMLComment(); 668c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLComment( const XMLComment& ); // not supported 669c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLComment& operator=( const XMLComment& ); // not supported 670c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 671c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieprivate: 672c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie}; 673c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 674c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 675c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie/** In correct XML the declaration is the first entry in the file. 676c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @verbatim 677c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie <?xml version="1.0" standalone="yes"?> 678c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @endverbatim 679c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 680c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie TinyXML2 will happily read or write files without a declaration, 681c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie however. 682c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 683c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie The text of the declaration isn't interpreted. It is parsed 684c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie and written as a string. 685c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie*/ 686c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieclass XMLDeclaration : public XMLNode 687c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 688c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie friend class XMLDocument; 689c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiepublic: 690c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual XMLDeclaration* ToDeclaration() { return this; } 691c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual const XMLDeclaration* ToDeclaration() const { return this; } 692c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 693c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual bool Accept( XMLVisitor* visitor ) const; 694c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 695c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char* ParseDeep( char*, StrPair* endTag ); 696c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual XMLNode* ShallowClone( XMLDocument* document ) const; 697c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual bool ShallowEqual( const XMLNode* compare ) const; 698c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 699c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieprotected: 700c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLDeclaration( XMLDocument* doc ); 701c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual ~XMLDeclaration(); 702c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLDeclaration( const XMLDeclaration& ); // not supported 703c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLDeclaration& operator=( const XMLDeclaration& ); // not supported 704c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie}; 705c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 706c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 707c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie/** Any tag that tinyXml doesn't recognize is saved as an 708c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie unknown. It is a tag of text, but should not be modified. 709c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie It will be written back to the XML, unchanged, when the file 710c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie is saved. 711c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 712c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie DTD tags get thrown into TiXmlUnknowns. 713c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie*/ 714c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieclass XMLUnknown : public XMLNode 715c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 716c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie friend class XMLDocument; 717c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiepublic: 718c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual XMLUnknown* ToUnknown() { return this; } 719c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual const XMLUnknown* ToUnknown() const { return this; } 720c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 721c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual bool Accept( XMLVisitor* visitor ) const; 722c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 723c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char* ParseDeep( char*, StrPair* endTag ); 724c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual XMLNode* ShallowClone( XMLDocument* document ) const; 725c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual bool ShallowEqual( const XMLNode* compare ) const; 726c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 727c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieprotected: 728c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLUnknown( XMLDocument* doc ); 729c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual ~XMLUnknown(); 730c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLUnknown( const XMLUnknown& ); // not supported 731c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLUnknown& operator=( const XMLUnknown& ); // not supported 732c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie}; 733c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 734c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 735c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieenum { 736c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XML_NO_ERROR = 0, 737c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XML_SUCCESS = 0, 738c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 739c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XML_NO_ATTRIBUTE, 740c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XML_WRONG_ATTRIBUTE_TYPE, 741c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 742c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XML_ERROR_FILE_NOT_FOUND, 743c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XML_ERROR_FILE_COULD_NOT_BE_OPENED, 744c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XML_ERROR_FILE_READ_ERROR, 745c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XML_ERROR_ELEMENT_MISMATCH, 746c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XML_ERROR_PARSING_ELEMENT, 747c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XML_ERROR_PARSING_ATTRIBUTE, 748c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XML_ERROR_IDENTIFYING_TAG, 749c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XML_ERROR_PARSING_TEXT, 750c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XML_ERROR_PARSING_CDATA, 751c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XML_ERROR_PARSING_COMMENT, 752c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XML_ERROR_PARSING_DECLARATION, 753c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XML_ERROR_PARSING_UNKNOWN, 754c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XML_ERROR_EMPTY_DOCUMENT, 755c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XML_ERROR_MISMATCHED_ELEMENT, 756c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XML_ERROR_PARSING, 757c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 758c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XML_CAN_NOT_CONVERT_TEXT, 759c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XML_NO_TEXT_NODE 760c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie}; 761c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 762c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 763c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie/** An attribute is a name-value pair. Elements have an arbitrary 764c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie number of attributes, each with a unique name. 765c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 766c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @note The attributes are not XMLNodes. You may only query the 767c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Next() attribute in a list. 768c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie*/ 769c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieclass XMLAttribute 770c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 771c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie friend class XMLElement; 772c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiepublic: 773c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const char* Name() const { return name.GetStr(); } ///< The name of the attribute. 774c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const char* Value() const { return value.GetStr(); } ///< The value of the attribute. 775c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLAttribute* Next() const { return next; } ///< The next attribute in the list. 776c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 777c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** IntAttribute interprets the attribute as an integer, and returns the value. 778c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie If the value isn't an integer, 0 will be returned. There is no error checking; 779c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie use QueryIntAttribute() if you need error checking. 780c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 781c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int IntValue() const { int i=0; QueryIntValue( &i ); return i; } 782c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Query as an unsigned integer. See IntAttribute() 783c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie unsigned UnsignedValue() const { unsigned i=0; QueryUnsignedValue( &i ); return i; } 784c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Query as a boolean. See IntAttribute() 785c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie bool BoolValue() const { bool b=false; QueryBoolValue( &b ); return b; } 786c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Query as a double. See IntAttribute() 787c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie double DoubleValue() const { double d=0; QueryDoubleValue( &d ); return d; } 788c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Query as a float. See IntAttribute() 789c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie float FloatValue() const { float f=0; QueryFloatValue( &f ); return f; } 790c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 791c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** QueryIntAttribute interprets the attribute as an integer, and returns the value 792c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie in the provided paremeter. The function will return XML_NO_ERROR on success, 793c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie and XML_WRONG_ATTRIBUTE_TYPE if the conversion is not successful. 794c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 795c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int QueryIntValue( int* value ) const; 796c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// See QueryIntAttribute 797c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int QueryUnsignedValue( unsigned int* value ) const; 798c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// See QueryIntAttribute 799c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int QueryBoolValue( bool* value ) const; 800c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// See QueryIntAttribute 801c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int QueryDoubleValue( double* value ) const; 802c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// See QueryIntAttribute 803c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int QueryFloatValue( float* value ) const; 804c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 805c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Set the attribute to a string value. 806c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void SetAttribute( const char* value ); 807c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Set the attribute to value. 808c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void SetAttribute( int value ); 809c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Set the attribute to value. 810c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void SetAttribute( unsigned value ); 811c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Set the attribute to value. 812c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void SetAttribute( bool value ); 813c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Set the attribute to value. 814c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void SetAttribute( double value ); 815c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Set the attribute to value. 816c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void SetAttribute( float value ); 817c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 818c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieprivate: 819c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie enum { BUF_SIZE = 200 }; 820c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 821c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLAttribute() : next( 0 ) {} 822c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual ~XMLAttribute() {} 823c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLAttribute( const XMLAttribute& ); // not supported 824c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void operator=( const XMLAttribute& ); // not supported 825c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void SetName( const char* name ); 826c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 827c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char* ParseDeep( char* p, bool processEntities ); 828c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 829c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie mutable StrPair name; 830c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie mutable StrPair value; 831c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLAttribute* next; 832c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie MemPool* memPool; 833c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie}; 834c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 835c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 836c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie/** The element is a container class. It has a value, the element name, 837c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie and can contain other elements, text, comments, and unknowns. 838c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Elements also contain an arbitrary number of attributes. 839c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie*/ 840c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieclass XMLElement : public XMLNode 841c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 842c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie friend class XMLBase; 843c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie friend class XMLDocument; 844c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiepublic: 845c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Get the name of an element (which is the Value() of the node.) 846c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const char* Name() const { return Value(); } 847c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Set the name of the element. 848c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void SetName( const char* str, bool staticMem=false ) { SetValue( str, staticMem ); } 849c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 850c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual XMLElement* ToElement() { return this; } 851c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual const XMLElement* ToElement() const { return this; } 852c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual bool Accept( XMLVisitor* visitor ) const; 853c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 854c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** Given an attribute name, Attribute() returns the value 855c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie for the attribute of that name, or null if none 856c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie exists. For example: 857c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 858c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @verbatim 859c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const char* value = ele->Attribute( "foo" ); 860c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @endverbatim 861c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 862c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie The 'value' parameter is normally null. However, if specified, 863c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie the attribute will only be returned if the 'name' and 'value' 864c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie match. This allow you to write code: 865c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 866c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @verbatim 867c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( ele->Attribute( "foo", "bar" ) ) callFooIsBar(); 868c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @endverbatim 869c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 870c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie rather than: 871c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @verbatim 872c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( ele->Attribute( "foo" ) ) { 873c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( strcmp( ele->Attribute( "foo" ), "bar" ) == 0 ) callFooIsBar(); 874c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 875c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @endverbatim 876c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 877c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const char* Attribute( const char* name, const char* value=0 ) const; 878c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 879c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** Given an attribute name, IntAttribute() returns the value 880c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie of the attribute interpreted as an integer. 0 will be 881c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie returned if there is an error. For a method with error 882c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie checking, see QueryIntAttribute() 883c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 884c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int IntAttribute( const char* name ) const { int i=0; QueryIntAttribute( name, &i ); return i; } 885c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// See IntAttribute() 886c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie unsigned UnsignedAttribute( const char* name ) const{ unsigned i=0; QueryUnsignedAttribute( name, &i ); return i; } 887c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// See IntAttribute() 888c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie bool BoolAttribute( const char* name ) const { bool b=false; QueryBoolAttribute( name, &b ); return b; } 889c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// See IntAttribute() 890c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie double DoubleAttribute( const char* name ) const { double d=0; QueryDoubleAttribute( name, &d ); return d; } 891c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// See IntAttribute() 892c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie float FloatAttribute( const char* name ) const { float f=0; QueryFloatAttribute( name, &f ); return f; } 893c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 894c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** Given an attribute name, QueryIntAttribute() returns 895c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XML_NO_ERROR, XML_WRONG_ATTRIBUTE_TYPE if the conversion 896c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie can't be performed, or XML_NO_ATTRIBUTE if the attribute 897c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie doesn't exist. If successful, the result of the conversion 898c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie will be written to 'value'. If not successful, nothing will 899c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie be written to 'value'. This allows you to provide default 900c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie value: 901c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 902c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @verbatim 903c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int value = 10; 904c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie QueryIntAttribute( "foo", &value ); // if "foo" isn't found, value will still be 10 905c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @endverbatim 906c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 907c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int QueryIntAttribute( const char* name, int* _value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return XML_NO_ATTRIBUTE; return a->QueryIntValue( _value ); } 908c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// See QueryIntAttribute() 909c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int QueryUnsignedAttribute( const char* name, unsigned int* _value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return XML_NO_ATTRIBUTE; return a->QueryUnsignedValue( _value ); } 910c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// See QueryIntAttribute() 911c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int QueryBoolAttribute( const char* name, bool* _value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return XML_NO_ATTRIBUTE; return a->QueryBoolValue( _value ); } 912c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// See QueryIntAttribute() 913c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int QueryDoubleAttribute( const char* name, double* _value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return XML_NO_ATTRIBUTE; return a->QueryDoubleValue( _value ); } 914c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// See QueryIntAttribute() 915c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int QueryFloatAttribute( const char* name, float* _value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return XML_NO_ATTRIBUTE; return a->QueryFloatValue( _value ); } 916c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 917c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Sets the named attribute to value. 918c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void SetAttribute( const char* name, const char* _value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( _value ); } 919c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Sets the named attribute to value. 920c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void SetAttribute( const char* name, int _value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( _value ); } 921c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Sets the named attribute to value. 922c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void SetAttribute( const char* name, unsigned _value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( _value ); } 923c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Sets the named attribute to value. 924c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void SetAttribute( const char* name, bool _value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( _value ); } 925c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Sets the named attribute to value. 926c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void SetAttribute( const char* name, double _value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( _value ); } 927c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 928c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** 929c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Delete an attribute. 930c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 931c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void DeleteAttribute( const char* name ); 932c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 933c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Return the first attribute in the list. 934c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLAttribute* FirstAttribute() const { return rootAttribute; } 935c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Query a specific attribute in the list. 936c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLAttribute* FindAttribute( const char* name ) const; 937c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 938c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** Convenience function for easy access to the text inside an element. Although easy 939c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie and concise, GetText() is limited compared to getting the TiXmlText child 940c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie and accessing it directly. 941c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 942c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie If the first child of 'this' is a TiXmlText, the GetText() 943c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie returns the character string of the Text node, else null is returned. 944c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 945c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie This is a convenient method for getting the text of simple contained text: 946c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @verbatim 947c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie <foo>This is text</foo> 948c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const char* str = fooElement->GetText(); 949c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @endverbatim 950c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 951c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 'str' will be a pointer to "This is text". 952c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 953c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Note that this function can be misleading. If the element foo was created from 954c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie this XML: 955c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @verbatim 956c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie <foo><b>This is text</b></foo> 957c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @endverbatim 958c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 959c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie then the value of str would be null. The first child node isn't a text node, it is 960c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie another element. From this XML: 961c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @verbatim 962c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie <foo>This is <b>text</b></foo> 963c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @endverbatim 964c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie GetText() will return "This is ". 965c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 966c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const char* GetText() const; 967c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 968c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** 969c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Convenience method to query the value of a child text node. This is probably best 970c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie shown by example. Given you have a document is this form: 971c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @verbatim 972c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie <point> 973c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie <x>1</x> 974c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie <y>1.4</y> 975c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie </point> 976c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @endverbatim 977c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 978c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie The QueryIntText() and similar functions provide a safe and easier way to get to the 979c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie "value" of x and y. 980c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 981c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @verbatim 982c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int x = 0; 983c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie float y = 0; // types of x and y are contrived for example 984c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLElement* xElement = pointElement->FirstChildElement( "x" ); 985c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLElement* yElement = pointElement->FirstChildElement( "y" ); 986c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie xElement->QueryIntText( &x ); 987c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie yElement->QueryFloatText( &y ); 988c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @endverbatim 989c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 990c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @returns XML_SUCCESS (0) on success, XML_CAN_NOT_CONVERT_TEXT if the text cannot be converted 991c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie to the requested type, and XML_NO_TEXT_NODE if there is no child text to query. 992c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 993c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 994c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int QueryIntText( int* _value ) const; 995c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// See QueryIntText() 996c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int QueryUnsignedText( unsigned* _value ) const; 997c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// See QueryIntText() 998c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int QueryBoolText( bool* _value ) const; 999c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// See QueryIntText() 1000c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int QueryDoubleText( double* _value ) const; 1001c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// See QueryIntText() 1002c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int QueryFloatText( float* _value ) const; 1003c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1004c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // internal: 1005c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie enum { 1006c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie OPEN, // <foo> 1007c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie CLOSED, // <foo/> 1008c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie CLOSING // </foo> 1009c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie }; 1010c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int ClosingType() const { return closingType; } 1011c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char* ParseDeep( char* p, StrPair* endTag ); 1012c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual XMLNode* ShallowClone( XMLDocument* document ) const; 1013c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual bool ShallowEqual( const XMLNode* compare ) const; 1014c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1015c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieprivate: 1016c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLElement( XMLDocument* doc ); 1017c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual ~XMLElement(); 1018c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLElement( const XMLElement& ); // not supported 1019c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void operator=( const XMLElement& ); // not supported 1020c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1021c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLAttribute* FindAttribute( const char* name ); 1022c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLAttribute* FindOrCreateAttribute( const char* name ); 1023c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie //void LinkAttribute( XMLAttribute* attrib ); 1024c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char* ParseAttributes( char* p ); 1025c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1026c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int closingType; 1027c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // The attribute list is ordered; there is no 'lastAttribute' 1028c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // because the list needs to be scanned for dupes before adding 1029c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // a new attribute. 1030c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLAttribute* rootAttribute; 1031c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie}; 1032c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1033c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1034c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie/** A Document binds together all the functionality. 1035c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie It can be saved, loaded, and printed to the screen. 1036c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie All Nodes are connected and allocated to a Document. 1037c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie If the Document is deleted, all its Nodes are also deleted. 1038c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie*/ 1039c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieclass XMLDocument : public XMLNode 1040c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1041c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie friend class XMLElement; 1042c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiepublic: 1043c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// constructor 1044c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLDocument( bool processEntities = true ); 1045c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ~XMLDocument(); 1046c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1047c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual XMLDocument* ToDocument() { return this; } 1048c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual const XMLDocument* ToDocument() const { return this; } 1049c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1050c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** 1051c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Parse an XML file from a character string. 1052c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Returns XML_NO_ERROR (0) on success, or 1053c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie an errorID. 1054c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 1055c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int Parse( const char* xml ); 1056c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1057c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** 1058c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Load an XML file from disk. 1059c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Returns XML_NO_ERROR (0) on success, or 1060c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie an errorID. 1061c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 1062c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int LoadFile( const char* filename ); 1063c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1064c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** 1065c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Load an XML file from disk. You are responsible 1066c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie for providing and closing the FILE*. 1067c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1068c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Returns XML_NO_ERROR (0) on success, or 1069c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie an errorID. 1070c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 1071c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int LoadFile( FILE* ); 1072c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1073c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** 1074c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Save the XML file to disk. 1075c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Returns XML_NO_ERROR (0) on success, or 1076c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie an errorID. 1077c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 1078c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int SaveFile( const char* filename ); 1079c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1080c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** 1081c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Save the XML file to disk. You are responsible 1082c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie for providing and closing the FILE*. 1083c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1084c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Returns XML_NO_ERROR (0) on success, or 1085c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie an errorID. 1086c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 1087c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int SaveFile( FILE* ); 1088c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1089c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie bool ProcessEntities() const { return processEntities; } 1090c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1091c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** 1092c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Returns true if this document has a leading Byte Order Mark of UTF8. 1093c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 1094c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie bool HasBOM() const { return writeBOM; } 1095c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** Sets whether to write the BOM when writing the file. 1096c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 1097c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void SetBOM( bool useBOM ) { writeBOM = useBOM; } 1098c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1099c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** Return the root element of DOM. Equivalent to FirstChildElement(). 1100c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie To get the first node, use FirstChild(). 1101c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 1102c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLElement* RootElement() { return FirstChildElement(); } 1103c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLElement* RootElement() const { return FirstChildElement(); } 1104c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1105c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** Print the Document. If the Printer is not provided, it will 1106c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie print to stdout. If you provide Printer, this can print to a file: 1107c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @verbatim 1108c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLPrinter printer( fp ); 1109c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie doc.Print( &printer ); 1110c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @endverbatim 1111c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1112c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Or you can use a printer to print to memory: 1113c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @verbatim 1114c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLPrinter printer; 1115c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie doc->Print( &printer ); 1116c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // printer.CStr() has a const char* to the XML 1117c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @endverbatim 1118c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 1119c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void Print( XMLPrinter* streamer=0 ); 1120c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual bool Accept( XMLVisitor* visitor ) const; 1121c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1122c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** 1123c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Create a new Element associated with 1124c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie this Document. The memory for the Element 1125c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie is managed by the Document. 1126c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 1127c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLElement* NewElement( const char* name ); 1128c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** 1129c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Create a new Comment associated with 1130c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie this Document. The memory for the Comment 1131c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie is managed by the Document. 1132c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 1133c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLComment* NewComment( const char* comment ); 1134c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** 1135c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Create a new Text associated with 1136c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie this Document. The memory for the Text 1137c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie is managed by the Document. 1138c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 1139c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLText* NewText( const char* text ); 1140c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** 1141c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Create a new Declaration associated with 1142c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie this Document. The memory for the object 1143c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie is managed by the Document. 1144c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1145c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie If the 'text' param is null, the standard 1146c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie declaration is used.: 1147c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @verbatim 1148c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie <?xml version="1.0" encoding="UTF-8"?> 1149c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @endverbatim 1150c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 1151c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLDeclaration* NewDeclaration( const char* text=0 ); 1152c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** 1153c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Create a new Unknown associated with 1154c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie this Document. The memory for the object 1155c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie is managed by the Document. 1156c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 1157c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLUnknown* NewUnknown( const char* text ); 1158c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1159c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** 1160c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Delete a node associated with this document. 1161c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie It will be unlinked from the DOM. 1162c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 1163c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void DeleteNode( XMLNode* node ) { node->parent->DeleteChild( node ); } 1164c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1165c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void SetError( int error, const char* str1, const char* str2 ); 1166c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1167c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Return true if there was an error parsing the document. 1168c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie bool Error() const { return errorID != XML_NO_ERROR; } 1169c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Return the errorID. 1170c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int ErrorID() const { return errorID; } 1171c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Return a possibly helpful diagnostic location or string. 1172c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const char* GetErrorStr1() const { return errorStr1; } 1173c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Return a possibly helpful secondary diagnostic location or string. 1174c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const char* GetErrorStr2() const { return errorStr2; } 1175c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// If there is an error, print it to stdout. 1176c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void PrintError() const; 1177c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1178c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // internal 1179c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char* Identify( char* p, XMLNode** node ); 1180c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1181c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const { return 0; } 1182c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual bool ShallowEqual( const XMLNode* /*compare*/ ) const { return false; } 1183c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1184c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieprivate: 1185c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLDocument( const XMLDocument& ); // not supported 1186c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void operator=( const XMLDocument& ); // not supported 1187c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void InitDocument(); 1188c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1189c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie bool writeBOM; 1190c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie bool processEntities; 1191c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int errorID; 1192c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const char* errorStr1; 1193c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const char* errorStr2; 1194c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char* charBuffer; 1195c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1196c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie MemPoolT< sizeof(XMLElement) > elementPool; 1197c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie MemPoolT< sizeof(XMLAttribute) > attributePool; 1198c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie MemPoolT< sizeof(XMLText) > textPool; 1199c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie MemPoolT< sizeof(XMLComment) > commentPool; 1200c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie}; 1201c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1202c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1203c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie/** 1204c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie A XMLHandle is a class that wraps a node pointer with null checks; this is 1205c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie an incredibly useful thing. Note that XMLHandle is not part of the TinyXML 1206c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie DOM structure. It is a separate utility class. 1207c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1208c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Take an example: 1209c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @verbatim 1210c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie <Document> 1211c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie <Element attributeA = "valueA"> 1212c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie <Child attributeB = "value1" /> 1213c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie <Child attributeB = "value2" /> 1214c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie </Element> 1215c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie </Document> 1216c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @endverbatim 1217c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1218c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very 1219c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie easy to write a *lot* of code that looks like: 1220c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1221c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @verbatim 1222c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLElement* root = document.FirstChildElement( "Document" ); 1223c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( root ) 1224c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { 1225c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLElement* element = root->FirstChildElement( "Element" ); 1226c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( element ) 1227c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { 1228c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLElement* child = element->FirstChildElement( "Child" ); 1229c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( child ) 1230c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { 1231c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLElement* child2 = child->NextSiblingElement( "Child" ); 1232c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( child2 ) 1233c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { 1234c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // Finally do something useful. 1235c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @endverbatim 1236c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1237c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie And that doesn't even cover "else" cases. XMLHandle addresses the verbosity 1238c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie of such code. A XMLHandle checks for null pointers so it is perfectly safe 1239c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie and correct to use: 1240c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1241c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @verbatim 1242c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLHandle docHandle( &document ); 1243c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild().NextSibling().ToElement(); 1244c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( child2 ) 1245c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { 1246c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // do something useful 1247c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @endverbatim 1248c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1249c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Which is MUCH more concise and useful. 1250c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1251c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie It is also safe to copy handles - internally they are nothing more than node pointers. 1252c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @verbatim 1253c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLHandle handleCopy = handle; 1254c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @endverbatim 1255c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1256c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie See also XMLConstHandle, which is the same as XMLHandle, but operates on const objects. 1257c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie*/ 1258c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieclass XMLHandle 1259c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1260c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiepublic: 1261c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. 1262c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLHandle( XMLNode* _node ) { node = _node; } 1263c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Create a handle from a node. 1264c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLHandle( XMLNode& _node ) { node = &_node; } 1265c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Copy constructor 1266c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLHandle( const XMLHandle& ref ) { node = ref.node; } 1267c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Assignment 1268c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLHandle& operator=( const XMLHandle& ref ) { node = ref.node; return *this; } 1269c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1270c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Get the first child of this handle. 1271c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLHandle FirstChild() { return XMLHandle( node ? node->FirstChild() : 0 ); } 1272c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Get the first child element of this handle. 1273c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLHandle FirstChildElement( const char* value=0 ) { return XMLHandle( node ? node->FirstChildElement( value ) : 0 ); } 1274c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Get the last child of this handle. 1275c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLHandle LastChild() { return XMLHandle( node ? node->LastChild() : 0 ); } 1276c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Get the last child element of this handle. 1277c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLHandle LastChildElement( const char* _value=0 ) { return XMLHandle( node ? node->LastChildElement( _value ) : 0 ); } 1278c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Get the previous sibling of this handle. 1279c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLHandle PreviousSibling() { return XMLHandle( node ? node->PreviousSibling() : 0 ); } 1280c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Get the previous sibling element of this handle. 1281c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLHandle PreviousSiblingElement( const char* _value=0 ) { return XMLHandle( node ? node->PreviousSiblingElement( _value ) : 0 ); } 1282c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Get the next sibling of this handle. 1283c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLHandle NextSibling() { return XMLHandle( node ? node->NextSibling() : 0 ); } 1284c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Get the next sibling element of this handle. 1285c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLHandle NextSiblingElement( const char* _value=0 ) { return XMLHandle( node ? node->NextSiblingElement( _value ) : 0 ); } 1286c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1287c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Safe cast to XMLNode. This can return null. 1288c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLNode* ToNode() { return node; } 1289c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Safe cast to XMLElement. This can return null. 1290c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLElement* ToElement() { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } 1291c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Safe cast to XMLText. This can return null. 1292c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLText* ToText() { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); } 1293c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Safe cast to XMLUnknown. This can return null. 1294c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLUnknown* ToUnknown() { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); } 1295c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Safe cast to XMLDeclaration. This can return null. 1296c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLDeclaration* ToDeclaration() { return ( ( node && node->ToDeclaration() ) ? node->ToDeclaration() : 0 ); } 1297c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1298c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieprivate: 1299c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLNode* node; 1300c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie}; 1301c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1302c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1303c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie/** 1304c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie A variant of the XMLHandle class for working with const XMLNodes and Documents. It is the 1305c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie same in all regards, except for the 'const' qualifiers. See XMLHandle for API. 1306c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie*/ 1307c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieclass XMLConstHandle 1308c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1309c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiepublic: 1310c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLConstHandle( const XMLNode* _node ) { node = _node; } 1311c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLConstHandle( const XMLNode& _node ) { node = &_node; } 1312c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLConstHandle( const XMLConstHandle& ref ) { node = ref.node; } 1313c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1314c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLConstHandle& operator=( const XMLConstHandle& ref ) { node = ref.node; return *this; } 1315c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1316c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLConstHandle FirstChild() const { return XMLConstHandle( node ? node->FirstChild() : 0 ); } 1317c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLConstHandle FirstChildElement( const char* value=0 ) const { return XMLConstHandle( node ? node->FirstChildElement( value ) : 0 ); } 1318c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLConstHandle LastChild() const { return XMLConstHandle( node ? node->LastChild() : 0 ); } 1319c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLConstHandle LastChildElement( const char* _value=0 ) const { return XMLConstHandle( node ? node->LastChildElement( _value ) : 0 ); } 1320c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLConstHandle PreviousSibling() const { return XMLConstHandle( node ? node->PreviousSibling() : 0 ); } 1321c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLConstHandle PreviousSiblingElement( const char* _value=0 ) const { return XMLConstHandle( node ? node->PreviousSiblingElement( _value ) : 0 ); } 1322c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLConstHandle NextSibling() const { return XMLConstHandle( node ? node->NextSibling() : 0 ); } 1323c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLConstHandle NextSiblingElement( const char* _value=0 ) const { return XMLConstHandle( node ? node->NextSiblingElement( _value ) : 0 ); } 1324c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1325c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1326c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLNode* ToNode() const { return node; } 1327c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLElement* ToElement() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } 1328c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLText* ToText() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); } 1329c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLUnknown* ToUnknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); } 1330c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLDeclaration* ToDeclaration() const { return ( ( node && node->ToDeclaration() ) ? node->ToDeclaration() : 0 ); } 1331c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1332c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieprivate: 1333c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLNode* node; 1334c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie}; 1335c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1336c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1337c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie/** 1338c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Printing functionality. The XMLPrinter gives you more 1339c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie options than the XMLDocument::Print() method. 1340c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1341c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie It can: 1342c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie -# Print to memory. 1343c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie -# Print to a file you provide. 1344c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie -# Print XML without a XMLDocument. 1345c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1346c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Print to Memory 1347c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1348c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @verbatim 1349c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLPrinter printer; 1350c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie doc->Print( &printer ); 1351c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie SomeFunction( printer.CStr() ); 1352c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @endverbatim 1353c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1354c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Print to a File 1355c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1356c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie You provide the file pointer. 1357c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @verbatim 1358c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLPrinter printer( fp ); 1359c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie doc.Print( &printer ); 1360c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @endverbatim 1361c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1362c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Print without a XMLDocument 1363c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1364c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie When loading, an XML parser is very useful. However, sometimes 1365c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie when saving, it just gets in the way. The code is often set up 1366c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie for streaming, and constructing the DOM is just overhead. 1367c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1368c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie The Printer supports the streaming case. The following code 1369c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie prints out a trivially simple XML file without ever creating 1370c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie an XML document. 1371c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1372c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @verbatim 1373c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLPrinter printer( fp ); 1374c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie printer.OpenElement( "foo" ); 1375c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie printer.PushAttribute( "foo", "bar" ); 1376c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie printer.CloseElement(); 1377c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie @endverbatim 1378c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie*/ 1379c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieclass XMLPrinter : public XMLVisitor 1380c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1381c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiepublic: 1382c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** Construct the printer. If the FILE* is specified, 1383c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie this will print to the FILE. Else it will print 1384c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie to memory, and the result is available in CStr(). 1385c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie If 'compact' is set to true, then output is created 1386c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie with only required whitespace and newlines. 1387c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 1388c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLPrinter( FILE* file=0, bool compact = false ); 1389c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ~XMLPrinter() {} 1390c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1391c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** If streaming, write the BOM and declaration. */ 1392c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void PushHeader( bool writeBOM, bool writeDeclaration ); 1393c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** If streaming, start writing an element. 1394c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie The element must be closed with CloseElement() 1395c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 1396c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void OpenElement( const char* name ); 1397c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// If streaming, add an attribute to an open element. 1398c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void PushAttribute( const char* name, const char* value ); 1399c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void PushAttribute( const char* name, int value ); 1400c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void PushAttribute( const char* name, unsigned value ); 1401c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void PushAttribute( const char* name, bool value ); 1402c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void PushAttribute( const char* name, double value ); 1403c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// If streaming, close the Element. 1404c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void CloseElement(); 1405c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1406c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Add a text node. 1407c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void PushText( const char* text, bool cdata=false ); 1408c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Add a text node from an integer. 1409c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void PushText( int value ); 1410c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Add a text node from an unsigned. 1411c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void PushText( unsigned value ); 1412c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Add a text node from a bool. 1413c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void PushText( bool value ); 1414c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Add a text node from a float. 1415c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void PushText( float value ); 1416c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Add a text node from a double. 1417c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void PushText( double value ); 1418c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1419c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /// Add a comment 1420c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void PushComment( const char* comment ); 1421c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1422c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void PushDeclaration( const char* value ); 1423c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void PushUnknown( const char* value ); 1424c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1425c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual bool VisitEnter( const XMLDocument& /*doc*/ ); 1426c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual bool VisitExit( const XMLDocument& /*doc*/ ) { return true; } 1427c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1428c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute ); 1429c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual bool VisitExit( const XMLElement& element ); 1430c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1431c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual bool Visit( const XMLText& text ); 1432c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual bool Visit( const XMLComment& comment ); 1433c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual bool Visit( const XMLDeclaration& declaration ); 1434c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie virtual bool Visit( const XMLUnknown& unknown ); 1435c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1436c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** 1437c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie If in print to memory mode, return a pointer to 1438c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie the XML file in memory. 1439c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 1440c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const char* CStr() const { return buffer.Mem(); } 1441c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie /** 1442c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie If in print to memory mode, return the size 1443c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie of the XML file in memory. (Note the size returned 1444c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie includes the terminating null.) 1445c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie */ 1446c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int CStrSize() const { return buffer.Size(); } 1447c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1448c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieprivate: 1449c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void SealElement(); 1450c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void PrintSpace( int depth ); 1451c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void PrintString( const char*, bool restrictedEntitySet ); // prints out, after detecting entities. 1452c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie void Print( const char* format, ... ); 1453c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1454c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie bool elementJustOpened; 1455c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie bool firstElement; 1456c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie FILE* fp; 1457c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int depth; 1458c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int textDepth; 1459c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie bool processEntities; 1460c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie bool compactMode; 1461c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1462c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie enum { 1463c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ENTITY_RANGE = 64, 1464c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie BUF_SIZE = 200 1465c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie }; 1466c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie bool entityFlag[ENTITY_RANGE]; 1467c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie bool restrictedEntityFlag[ENTITY_RANGE]; 1468c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1469c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie DynArray< const char*, 10 > stack; 1470c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie DynArray< char, 20 > buffer; 1471c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#ifdef _MSC_VER 1472c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie DynArray< char, 20 > accumulator; 1473c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#endif 1474c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie}; 1475c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1476c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1477c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} // tinyxml2 1478c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1479c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1480c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#endif // TINYXML2_INCLUDED 1481