Alexander Steiger / tinyxml
Committer:
steiger
Date:
Sun Nov 21 00:49:17 2010 +0000
Revision:
0:7c97dcef700c

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
steiger 0:7c97dcef700c 1 /*
steiger 0:7c97dcef700c 2 www.sourceforge.net/projects/tinyxml
steiger 0:7c97dcef700c 3 Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
steiger 0:7c97dcef700c 4
steiger 0:7c97dcef700c 5 This software is provided 'as-is', without any express or implied
steiger 0:7c97dcef700c 6 warranty. In no event will the authors be held liable for any
steiger 0:7c97dcef700c 7 damages arising from the use of this software.
steiger 0:7c97dcef700c 8
steiger 0:7c97dcef700c 9 Permission is granted to anyone to use this software for any
steiger 0:7c97dcef700c 10 purpose, including commercial applications, and to alter it and
steiger 0:7c97dcef700c 11 redistribute it freely, subject to the following restrictions:
steiger 0:7c97dcef700c 12
steiger 0:7c97dcef700c 13 1. The origin of this software must not be misrepresented; you must
steiger 0:7c97dcef700c 14 not claim that you wrote the original software. If you use this
steiger 0:7c97dcef700c 15 software in a product, an acknowledgment in the product documentation
steiger 0:7c97dcef700c 16 would be appreciated but is not required.
steiger 0:7c97dcef700c 17
steiger 0:7c97dcef700c 18 2. Altered source versions must be plainly marked as such, and
steiger 0:7c97dcef700c 19 must not be misrepresented as being the original software.
steiger 0:7c97dcef700c 20
steiger 0:7c97dcef700c 21 3. This notice may not be removed or altered from any source
steiger 0:7c97dcef700c 22 distribution.
steiger 0:7c97dcef700c 23 */
steiger 0:7c97dcef700c 24
steiger 0:7c97dcef700c 25
steiger 0:7c97dcef700c 26 #ifndef TINYXML_INCLUDED
steiger 0:7c97dcef700c 27 #define TINYXML_INCLUDED
steiger 0:7c97dcef700c 28
steiger 0:7c97dcef700c 29 #ifdef _MSC_VER
steiger 0:7c97dcef700c 30 #pragma warning( push )
steiger 0:7c97dcef700c 31 #pragma warning( disable : 4530 )
steiger 0:7c97dcef700c 32 #pragma warning( disable : 4786 )
steiger 0:7c97dcef700c 33 #endif
steiger 0:7c97dcef700c 34
steiger 0:7c97dcef700c 35 #include <ctype.h>
steiger 0:7c97dcef700c 36 #include <stdio.h>
steiger 0:7c97dcef700c 37 #include <stdlib.h>
steiger 0:7c97dcef700c 38 #include <string.h>
steiger 0:7c97dcef700c 39 #include <assert.h>
steiger 0:7c97dcef700c 40
steiger 0:7c97dcef700c 41 // Help out windows:
steiger 0:7c97dcef700c 42 #if defined( _DEBUG ) && !defined( DEBUG )
steiger 0:7c97dcef700c 43 #define DEBUG
steiger 0:7c97dcef700c 44 #endif
steiger 0:7c97dcef700c 45
steiger 0:7c97dcef700c 46 #ifdef TIXML_USE_STL
steiger 0:7c97dcef700c 47 #include <string>
steiger 0:7c97dcef700c 48 #include <iostream>
steiger 0:7c97dcef700c 49 #include <sstream>
steiger 0:7c97dcef700c 50 #define TIXML_STRING std::string
steiger 0:7c97dcef700c 51 #else
steiger 0:7c97dcef700c 52 #include "tinystr.h"
steiger 0:7c97dcef700c 53 #define TIXML_STRING TiXmlString
steiger 0:7c97dcef700c 54 #endif
steiger 0:7c97dcef700c 55
steiger 0:7c97dcef700c 56 // Deprecated library function hell. Compilers want to use the
steiger 0:7c97dcef700c 57 // new safe versions. This probably doesn't fully address the problem,
steiger 0:7c97dcef700c 58 // but it gets closer. There are too many compilers for me to fully
steiger 0:7c97dcef700c 59 // test. If you get compilation troubles, undefine TIXML_SAFE
steiger 0:7c97dcef700c 60 #define TIXML_SAFE
steiger 0:7c97dcef700c 61
steiger 0:7c97dcef700c 62 #ifdef TIXML_SAFE
steiger 0:7c97dcef700c 63 #if defined(_MSC_VER) && (_MSC_VER >= 1400 )
steiger 0:7c97dcef700c 64 // Microsoft visual studio, version 2005 and higher.
steiger 0:7c97dcef700c 65 #define TIXML_SNPRINTF _snprintf_s
steiger 0:7c97dcef700c 66 #define TIXML_SSCANF sscanf_s
steiger 0:7c97dcef700c 67 #elif defined(_MSC_VER) && (_MSC_VER >= 1200 )
steiger 0:7c97dcef700c 68 // Microsoft visual studio, version 6 and higher.
steiger 0:7c97dcef700c 69 //#pragma message( "Using _sn* functions." )
steiger 0:7c97dcef700c 70 #define TIXML_SNPRINTF _snprintf
steiger 0:7c97dcef700c 71 #define TIXML_SSCANF sscanf
steiger 0:7c97dcef700c 72 #elif defined(__GNUC__) && (__GNUC__ >= 3 )
steiger 0:7c97dcef700c 73 // GCC version 3 and higher.s
steiger 0:7c97dcef700c 74 //#warning( "Using sn* functions." )
steiger 0:7c97dcef700c 75 #define TIXML_SNPRINTF snprintf
steiger 0:7c97dcef700c 76 #define TIXML_SSCANF sscanf
steiger 0:7c97dcef700c 77 #else
steiger 0:7c97dcef700c 78 #define TIXML_SNPRINTF snprintf
steiger 0:7c97dcef700c 79 #define TIXML_SSCANF sscanf
steiger 0:7c97dcef700c 80 #endif
steiger 0:7c97dcef700c 81 #endif
steiger 0:7c97dcef700c 82
steiger 0:7c97dcef700c 83 class TiXmlDocument;
steiger 0:7c97dcef700c 84 class TiXmlElement;
steiger 0:7c97dcef700c 85 class TiXmlComment;
steiger 0:7c97dcef700c 86 class TiXmlUnknown;
steiger 0:7c97dcef700c 87 class TiXmlAttribute;
steiger 0:7c97dcef700c 88 class TiXmlText;
steiger 0:7c97dcef700c 89 class TiXmlDeclaration;
steiger 0:7c97dcef700c 90 class TiXmlParsingData;
steiger 0:7c97dcef700c 91
steiger 0:7c97dcef700c 92 const int TIXML_MAJOR_VERSION = 2;
steiger 0:7c97dcef700c 93 const int TIXML_MINOR_VERSION = 6;
steiger 0:7c97dcef700c 94 const int TIXML_PATCH_VERSION = 1;
steiger 0:7c97dcef700c 95
steiger 0:7c97dcef700c 96 /* Internal structure for tracking location of items
steiger 0:7c97dcef700c 97 in the XML file.
steiger 0:7c97dcef700c 98 */
steiger 0:7c97dcef700c 99 struct TiXmlCursor
steiger 0:7c97dcef700c 100 {
steiger 0:7c97dcef700c 101 TiXmlCursor() { Clear(); }
steiger 0:7c97dcef700c 102 void Clear() { row = col = -1; }
steiger 0:7c97dcef700c 103
steiger 0:7c97dcef700c 104 int row; // 0 based.
steiger 0:7c97dcef700c 105 int col; // 0 based.
steiger 0:7c97dcef700c 106 };
steiger 0:7c97dcef700c 107
steiger 0:7c97dcef700c 108
steiger 0:7c97dcef700c 109 /**
steiger 0:7c97dcef700c 110 Implements the interface to the "Visitor pattern" (see the Accept() method.)
steiger 0:7c97dcef700c 111 If you call the Accept() method, it requires being passed a TiXmlVisitor
steiger 0:7c97dcef700c 112 class to handle callbacks. For nodes that contain other nodes (Document, Element)
steiger 0:7c97dcef700c 113 you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves
steiger 0:7c97dcef700c 114 are simply called with Visit().
steiger 0:7c97dcef700c 115
steiger 0:7c97dcef700c 116 If you return 'true' from a Visit method, recursive parsing will continue. If you return
steiger 0:7c97dcef700c 117 false, <b>no children of this node or its sibilings</b> will be Visited.
steiger 0:7c97dcef700c 118
steiger 0:7c97dcef700c 119 All flavors of Visit methods have a default implementation that returns 'true' (continue
steiger 0:7c97dcef700c 120 visiting). You need to only override methods that are interesting to you.
steiger 0:7c97dcef700c 121
steiger 0:7c97dcef700c 122 Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting.
steiger 0:7c97dcef700c 123
steiger 0:7c97dcef700c 124 You should never change the document from a callback.
steiger 0:7c97dcef700c 125
steiger 0:7c97dcef700c 126 @sa TiXmlNode::Accept()
steiger 0:7c97dcef700c 127 */
steiger 0:7c97dcef700c 128 class TiXmlVisitor
steiger 0:7c97dcef700c 129 {
steiger 0:7c97dcef700c 130 public:
steiger 0:7c97dcef700c 131 virtual ~TiXmlVisitor() {}
steiger 0:7c97dcef700c 132
steiger 0:7c97dcef700c 133 /// Visit a document.
steiger 0:7c97dcef700c 134 virtual bool VisitEnter( const TiXmlDocument& /*doc*/ ) { return true; }
steiger 0:7c97dcef700c 135 /// Visit a document.
steiger 0:7c97dcef700c 136 virtual bool VisitExit( const TiXmlDocument& /*doc*/ ) { return true; }
steiger 0:7c97dcef700c 137
steiger 0:7c97dcef700c 138 /// Visit an element.
steiger 0:7c97dcef700c 139 virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ ) { return true; }
steiger 0:7c97dcef700c 140 /// Visit an element.
steiger 0:7c97dcef700c 141 virtual bool VisitExit( const TiXmlElement& /*element*/ ) { return true; }
steiger 0:7c97dcef700c 142
steiger 0:7c97dcef700c 143 /// Visit a declaration
steiger 0:7c97dcef700c 144 virtual bool Visit( const TiXmlDeclaration& /*declaration*/ ) { return true; }
steiger 0:7c97dcef700c 145 /// Visit a text node
steiger 0:7c97dcef700c 146 virtual bool Visit( const TiXmlText& /*text*/ ) { return true; }
steiger 0:7c97dcef700c 147 /// Visit a comment node
steiger 0:7c97dcef700c 148 virtual bool Visit( const TiXmlComment& /*comment*/ ) { return true; }
steiger 0:7c97dcef700c 149 /// Visit an unknow node
steiger 0:7c97dcef700c 150 virtual bool Visit( const TiXmlUnknown& /*unknown*/ ) { return true; }
steiger 0:7c97dcef700c 151 };
steiger 0:7c97dcef700c 152
steiger 0:7c97dcef700c 153 // Only used by Attribute::Query functions
steiger 0:7c97dcef700c 154 enum
steiger 0:7c97dcef700c 155 {
steiger 0:7c97dcef700c 156 TIXML_SUCCESS,
steiger 0:7c97dcef700c 157 TIXML_NO_ATTRIBUTE,
steiger 0:7c97dcef700c 158 TIXML_WRONG_TYPE
steiger 0:7c97dcef700c 159 };
steiger 0:7c97dcef700c 160
steiger 0:7c97dcef700c 161
steiger 0:7c97dcef700c 162 // Used by the parsing routines.
steiger 0:7c97dcef700c 163 enum TiXmlEncoding
steiger 0:7c97dcef700c 164 {
steiger 0:7c97dcef700c 165 TIXML_ENCODING_UNKNOWN,
steiger 0:7c97dcef700c 166 TIXML_ENCODING_UTF8,
steiger 0:7c97dcef700c 167 TIXML_ENCODING_LEGACY
steiger 0:7c97dcef700c 168 };
steiger 0:7c97dcef700c 169
steiger 0:7c97dcef700c 170 const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN;
steiger 0:7c97dcef700c 171
steiger 0:7c97dcef700c 172 /** TiXmlBase is a base class for every class in TinyXml.
steiger 0:7c97dcef700c 173 It does little except to establish that TinyXml classes
steiger 0:7c97dcef700c 174 can be printed and provide some utility functions.
steiger 0:7c97dcef700c 175
steiger 0:7c97dcef700c 176 In XML, the document and elements can contain
steiger 0:7c97dcef700c 177 other elements and other types of nodes.
steiger 0:7c97dcef700c 178
steiger 0:7c97dcef700c 179 @verbatim
steiger 0:7c97dcef700c 180 A Document can contain: Element (container or leaf)
steiger 0:7c97dcef700c 181 Comment (leaf)
steiger 0:7c97dcef700c 182 Unknown (leaf)
steiger 0:7c97dcef700c 183 Declaration( leaf )
steiger 0:7c97dcef700c 184
steiger 0:7c97dcef700c 185 An Element can contain: Element (container or leaf)
steiger 0:7c97dcef700c 186 Text (leaf)
steiger 0:7c97dcef700c 187 Attributes (not on tree)
steiger 0:7c97dcef700c 188 Comment (leaf)
steiger 0:7c97dcef700c 189 Unknown (leaf)
steiger 0:7c97dcef700c 190
steiger 0:7c97dcef700c 191 A Decleration contains: Attributes (not on tree)
steiger 0:7c97dcef700c 192 @endverbatim
steiger 0:7c97dcef700c 193 */
steiger 0:7c97dcef700c 194 class TiXmlBase
steiger 0:7c97dcef700c 195 {
steiger 0:7c97dcef700c 196 friend class TiXmlNode;
steiger 0:7c97dcef700c 197 friend class TiXmlElement;
steiger 0:7c97dcef700c 198 friend class TiXmlDocument;
steiger 0:7c97dcef700c 199
steiger 0:7c97dcef700c 200 public:
steiger 0:7c97dcef700c 201 TiXmlBase() : userData(0) {}
steiger 0:7c97dcef700c 202 virtual ~TiXmlBase() {}
steiger 0:7c97dcef700c 203
steiger 0:7c97dcef700c 204 /** All TinyXml classes can print themselves to a filestream
steiger 0:7c97dcef700c 205 or the string class (TiXmlString in non-STL mode, std::string
steiger 0:7c97dcef700c 206 in STL mode.) Either or both cfile and str can be null.
steiger 0:7c97dcef700c 207
steiger 0:7c97dcef700c 208 This is a formatted print, and will insert
steiger 0:7c97dcef700c 209 tabs and newlines.
steiger 0:7c97dcef700c 210
steiger 0:7c97dcef700c 211 (For an unformatted stream, use the << operator.)
steiger 0:7c97dcef700c 212 */
steiger 0:7c97dcef700c 213 virtual void Print( FILE* cfile, int depth ) const = 0;
steiger 0:7c97dcef700c 214
steiger 0:7c97dcef700c 215 /** The world does not agree on whether white space should be kept or
steiger 0:7c97dcef700c 216 not. In order to make everyone happy, these global, static functions
steiger 0:7c97dcef700c 217 are provided to set whether or not TinyXml will condense all white space
steiger 0:7c97dcef700c 218 into a single space or not. The default is to condense. Note changing this
steiger 0:7c97dcef700c 219 value is not thread safe.
steiger 0:7c97dcef700c 220 */
steiger 0:7c97dcef700c 221 static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; }
steiger 0:7c97dcef700c 222
steiger 0:7c97dcef700c 223 /// Return the current white space setting.
steiger 0:7c97dcef700c 224 static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace; }
steiger 0:7c97dcef700c 225
steiger 0:7c97dcef700c 226 /** Return the position, in the original source file, of this node or attribute.
steiger 0:7c97dcef700c 227 The row and column are 1-based. (That is the first row and first column is
steiger 0:7c97dcef700c 228 1,1). If the returns values are 0 or less, then the parser does not have
steiger 0:7c97dcef700c 229 a row and column value.
steiger 0:7c97dcef700c 230
steiger 0:7c97dcef700c 231 Generally, the row and column value will be set when the TiXmlDocument::Load(),
steiger 0:7c97dcef700c 232 TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set
steiger 0:7c97dcef700c 233 when the DOM was created from operator>>.
steiger 0:7c97dcef700c 234
steiger 0:7c97dcef700c 235 The values reflect the initial load. Once the DOM is modified programmatically
steiger 0:7c97dcef700c 236 (by adding or changing nodes and attributes) the new values will NOT update to
steiger 0:7c97dcef700c 237 reflect changes in the document.
steiger 0:7c97dcef700c 238
steiger 0:7c97dcef700c 239 There is a minor performance cost to computing the row and column. Computation
steiger 0:7c97dcef700c 240 can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value.
steiger 0:7c97dcef700c 241
steiger 0:7c97dcef700c 242 @sa TiXmlDocument::SetTabSize()
steiger 0:7c97dcef700c 243 */
steiger 0:7c97dcef700c 244 int Row() const { return location.row + 1; }
steiger 0:7c97dcef700c 245 int Column() const { return location.col + 1; } ///< See Row()
steiger 0:7c97dcef700c 246
steiger 0:7c97dcef700c 247 void SetUserData( void* user ) { userData = user; } ///< Set a pointer to arbitrary user data.
steiger 0:7c97dcef700c 248 void* GetUserData() { return userData; } ///< Get a pointer to arbitrary user data.
steiger 0:7c97dcef700c 249 const void* GetUserData() const { return userData; } ///< Get a pointer to arbitrary user data.
steiger 0:7c97dcef700c 250
steiger 0:7c97dcef700c 251 // Table that returs, for a given lead byte, the total number of bytes
steiger 0:7c97dcef700c 252 // in the UTF-8 sequence.
steiger 0:7c97dcef700c 253 static const int utf8ByteTable[256];
steiger 0:7c97dcef700c 254
steiger 0:7c97dcef700c 255 virtual const char* Parse( const char* p,
steiger 0:7c97dcef700c 256 TiXmlParsingData* data,
steiger 0:7c97dcef700c 257 TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0;
steiger 0:7c97dcef700c 258
steiger 0:7c97dcef700c 259 /** Expands entities in a string. Note this should not contian the tag's '<', '>', etc,
steiger 0:7c97dcef700c 260 or they will be transformed into entities!
steiger 0:7c97dcef700c 261 */
steiger 0:7c97dcef700c 262 static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out );
steiger 0:7c97dcef700c 263
steiger 0:7c97dcef700c 264 enum
steiger 0:7c97dcef700c 265 {
steiger 0:7c97dcef700c 266 TIXML_NO_ERROR = 0,
steiger 0:7c97dcef700c 267 TIXML_ERROR,
steiger 0:7c97dcef700c 268 TIXML_ERROR_OPENING_FILE,
steiger 0:7c97dcef700c 269 TIXML_ERROR_PARSING_ELEMENT,
steiger 0:7c97dcef700c 270 TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
steiger 0:7c97dcef700c 271 TIXML_ERROR_READING_ELEMENT_VALUE,
steiger 0:7c97dcef700c 272 TIXML_ERROR_READING_ATTRIBUTES,
steiger 0:7c97dcef700c 273 TIXML_ERROR_PARSING_EMPTY,
steiger 0:7c97dcef700c 274 TIXML_ERROR_READING_END_TAG,
steiger 0:7c97dcef700c 275 TIXML_ERROR_PARSING_UNKNOWN,
steiger 0:7c97dcef700c 276 TIXML_ERROR_PARSING_COMMENT,
steiger 0:7c97dcef700c 277 TIXML_ERROR_PARSING_DECLARATION,
steiger 0:7c97dcef700c 278 TIXML_ERROR_DOCUMENT_EMPTY,
steiger 0:7c97dcef700c 279 TIXML_ERROR_EMBEDDED_NULL,
steiger 0:7c97dcef700c 280 TIXML_ERROR_PARSING_CDATA,
steiger 0:7c97dcef700c 281 TIXML_ERROR_DOCUMENT_TOP_ONLY,
steiger 0:7c97dcef700c 282
steiger 0:7c97dcef700c 283 TIXML_ERROR_STRING_COUNT
steiger 0:7c97dcef700c 284 };
steiger 0:7c97dcef700c 285
steiger 0:7c97dcef700c 286 protected:
steiger 0:7c97dcef700c 287
steiger 0:7c97dcef700c 288 static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding );
steiger 0:7c97dcef700c 289
steiger 0:7c97dcef700c 290 inline static bool IsWhiteSpace( char c )
steiger 0:7c97dcef700c 291 {
steiger 0:7c97dcef700c 292 return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' );
steiger 0:7c97dcef700c 293 }
steiger 0:7c97dcef700c 294 inline static bool IsWhiteSpace( int c )
steiger 0:7c97dcef700c 295 {
steiger 0:7c97dcef700c 296 if ( c < 256 )
steiger 0:7c97dcef700c 297 return IsWhiteSpace( (char) c );
steiger 0:7c97dcef700c 298 return false; // Again, only truly correct for English/Latin...but usually works.
steiger 0:7c97dcef700c 299 }
steiger 0:7c97dcef700c 300
steiger 0:7c97dcef700c 301 #ifdef TIXML_USE_STL
steiger 0:7c97dcef700c 302 static bool StreamWhiteSpace( std::istream * in, TIXML_STRING * tag );
steiger 0:7c97dcef700c 303 static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag );
steiger 0:7c97dcef700c 304 #endif
steiger 0:7c97dcef700c 305
steiger 0:7c97dcef700c 306 /* Reads an XML name into the string provided. Returns
steiger 0:7c97dcef700c 307 a pointer just past the last character of the name,
steiger 0:7c97dcef700c 308 or 0 if the function has an error.
steiger 0:7c97dcef700c 309 */
steiger 0:7c97dcef700c 310 static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding );
steiger 0:7c97dcef700c 311
steiger 0:7c97dcef700c 312 /* Reads text. Returns a pointer past the given end tag.
steiger 0:7c97dcef700c 313 Wickedly complex options, but it keeps the (sensitive) code in one place.
steiger 0:7c97dcef700c 314 */
steiger 0:7c97dcef700c 315 static const char* ReadText( const char* in, // where to start
steiger 0:7c97dcef700c 316 TIXML_STRING* text, // the string read
steiger 0:7c97dcef700c 317 bool ignoreWhiteSpace, // whether to keep the white space
steiger 0:7c97dcef700c 318 const char* endTag, // what ends this text
steiger 0:7c97dcef700c 319 bool ignoreCase, // whether to ignore case in the end tag
steiger 0:7c97dcef700c 320 TiXmlEncoding encoding ); // the current encoding
steiger 0:7c97dcef700c 321
steiger 0:7c97dcef700c 322 // If an entity has been found, transform it into a character.
steiger 0:7c97dcef700c 323 static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding );
steiger 0:7c97dcef700c 324
steiger 0:7c97dcef700c 325 // Get a character, while interpreting entities.
steiger 0:7c97dcef700c 326 // The length can be from 0 to 4 bytes.
steiger 0:7c97dcef700c 327 inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding )
steiger 0:7c97dcef700c 328 {
steiger 0:7c97dcef700c 329 assert( p );
steiger 0:7c97dcef700c 330 if ( encoding == TIXML_ENCODING_UTF8 )
steiger 0:7c97dcef700c 331 {
steiger 0:7c97dcef700c 332 *length = utf8ByteTable[ *((const unsigned char*)p) ];
steiger 0:7c97dcef700c 333 assert( *length >= 0 && *length < 5 );
steiger 0:7c97dcef700c 334 }
steiger 0:7c97dcef700c 335 else
steiger 0:7c97dcef700c 336 {
steiger 0:7c97dcef700c 337 *length = 1;
steiger 0:7c97dcef700c 338 }
steiger 0:7c97dcef700c 339
steiger 0:7c97dcef700c 340 if ( *length == 1 )
steiger 0:7c97dcef700c 341 {
steiger 0:7c97dcef700c 342 if ( *p == '&' )
steiger 0:7c97dcef700c 343 return GetEntity( p, _value, length, encoding );
steiger 0:7c97dcef700c 344 *_value = *p;
steiger 0:7c97dcef700c 345 return p+1;
steiger 0:7c97dcef700c 346 }
steiger 0:7c97dcef700c 347 else if ( *length )
steiger 0:7c97dcef700c 348 {
steiger 0:7c97dcef700c 349 //strncpy( _value, p, *length ); // lots of compilers don't like this function (unsafe),
steiger 0:7c97dcef700c 350 // and the null terminator isn't needed
steiger 0:7c97dcef700c 351 for( int i=0; p[i] && i<*length; ++i ) {
steiger 0:7c97dcef700c 352 _value[i] = p[i];
steiger 0:7c97dcef700c 353 }
steiger 0:7c97dcef700c 354 return p + (*length);
steiger 0:7c97dcef700c 355 }
steiger 0:7c97dcef700c 356 else
steiger 0:7c97dcef700c 357 {
steiger 0:7c97dcef700c 358 // Not valid text.
steiger 0:7c97dcef700c 359 return 0;
steiger 0:7c97dcef700c 360 }
steiger 0:7c97dcef700c 361 }
steiger 0:7c97dcef700c 362
steiger 0:7c97dcef700c 363 // Return true if the next characters in the stream are any of the endTag sequences.
steiger 0:7c97dcef700c 364 // Ignore case only works for english, and should only be relied on when comparing
steiger 0:7c97dcef700c 365 // to English words: StringEqual( p, "version", true ) is fine.
steiger 0:7c97dcef700c 366 static bool StringEqual( const char* p,
steiger 0:7c97dcef700c 367 const char* endTag,
steiger 0:7c97dcef700c 368 bool ignoreCase,
steiger 0:7c97dcef700c 369 TiXmlEncoding encoding );
steiger 0:7c97dcef700c 370
steiger 0:7c97dcef700c 371 static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
steiger 0:7c97dcef700c 372
steiger 0:7c97dcef700c 373 TiXmlCursor location;
steiger 0:7c97dcef700c 374
steiger 0:7c97dcef700c 375 /// Field containing a generic user pointer
steiger 0:7c97dcef700c 376 void* userData;
steiger 0:7c97dcef700c 377
steiger 0:7c97dcef700c 378 // None of these methods are reliable for any language except English.
steiger 0:7c97dcef700c 379 // Good for approximation, not great for accuracy.
steiger 0:7c97dcef700c 380 static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding );
steiger 0:7c97dcef700c 381 static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding );
steiger 0:7c97dcef700c 382 inline static int ToLower( int v, TiXmlEncoding encoding )
steiger 0:7c97dcef700c 383 {
steiger 0:7c97dcef700c 384 if ( encoding == TIXML_ENCODING_UTF8 )
steiger 0:7c97dcef700c 385 {
steiger 0:7c97dcef700c 386 if ( v < 128 ) return tolower( v );
steiger 0:7c97dcef700c 387 return v;
steiger 0:7c97dcef700c 388 }
steiger 0:7c97dcef700c 389 else
steiger 0:7c97dcef700c 390 {
steiger 0:7c97dcef700c 391 return tolower( v );
steiger 0:7c97dcef700c 392 }
steiger 0:7c97dcef700c 393 }
steiger 0:7c97dcef700c 394 static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
steiger 0:7c97dcef700c 395
steiger 0:7c97dcef700c 396 private:
steiger 0:7c97dcef700c 397 TiXmlBase( const TiXmlBase& ); // not implemented.
steiger 0:7c97dcef700c 398 void operator=( const TiXmlBase& base ); // not allowed.
steiger 0:7c97dcef700c 399
steiger 0:7c97dcef700c 400 struct Entity
steiger 0:7c97dcef700c 401 {
steiger 0:7c97dcef700c 402 const char* str;
steiger 0:7c97dcef700c 403 unsigned int strLength;
steiger 0:7c97dcef700c 404 char chr;
steiger 0:7c97dcef700c 405 };
steiger 0:7c97dcef700c 406 enum
steiger 0:7c97dcef700c 407 {
steiger 0:7c97dcef700c 408 NUM_ENTITY = 5,
steiger 0:7c97dcef700c 409 MAX_ENTITY_LENGTH = 6
steiger 0:7c97dcef700c 410
steiger 0:7c97dcef700c 411 };
steiger 0:7c97dcef700c 412 static Entity entity[ NUM_ENTITY ];
steiger 0:7c97dcef700c 413 static bool condenseWhiteSpace;
steiger 0:7c97dcef700c 414 };
steiger 0:7c97dcef700c 415
steiger 0:7c97dcef700c 416
steiger 0:7c97dcef700c 417 /** The parent class for everything in the Document Object Model.
steiger 0:7c97dcef700c 418 (Except for attributes).
steiger 0:7c97dcef700c 419 Nodes have siblings, a parent, and children. A node can be
steiger 0:7c97dcef700c 420 in a document, or stand on its own. The type of a TiXmlNode
steiger 0:7c97dcef700c 421 can be queried, and it can be cast to its more defined type.
steiger 0:7c97dcef700c 422 */
steiger 0:7c97dcef700c 423 class TiXmlNode : public TiXmlBase
steiger 0:7c97dcef700c 424 {
steiger 0:7c97dcef700c 425 friend class TiXmlDocument;
steiger 0:7c97dcef700c 426 friend class TiXmlElement;
steiger 0:7c97dcef700c 427
steiger 0:7c97dcef700c 428 public:
steiger 0:7c97dcef700c 429 #ifdef TIXML_USE_STL
steiger 0:7c97dcef700c 430
steiger 0:7c97dcef700c 431 /** An input stream operator, for every class. Tolerant of newlines and
steiger 0:7c97dcef700c 432 formatting, but doesn't expect them.
steiger 0:7c97dcef700c 433 */
steiger 0:7c97dcef700c 434 friend std::istream& operator >> (std::istream& in, TiXmlNode& base);
steiger 0:7c97dcef700c 435
steiger 0:7c97dcef700c 436 /** An output stream operator, for every class. Note that this outputs
steiger 0:7c97dcef700c 437 without any newlines or formatting, as opposed to Print(), which
steiger 0:7c97dcef700c 438 includes tabs and new lines.
steiger 0:7c97dcef700c 439
steiger 0:7c97dcef700c 440 The operator<< and operator>> are not completely symmetric. Writing
steiger 0:7c97dcef700c 441 a node to a stream is very well defined. You'll get a nice stream
steiger 0:7c97dcef700c 442 of output, without any extra whitespace or newlines.
steiger 0:7c97dcef700c 443
steiger 0:7c97dcef700c 444 But reading is not as well defined. (As it always is.) If you create
steiger 0:7c97dcef700c 445 a TiXmlElement (for example) and read that from an input stream,
steiger 0:7c97dcef700c 446 the text needs to define an element or junk will result. This is
steiger 0:7c97dcef700c 447 true of all input streams, but it's worth keeping in mind.
steiger 0:7c97dcef700c 448
steiger 0:7c97dcef700c 449 A TiXmlDocument will read nodes until it reads a root element, and
steiger 0:7c97dcef700c 450 all the children of that root element.
steiger 0:7c97dcef700c 451 */
steiger 0:7c97dcef700c 452 friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base);
steiger 0:7c97dcef700c 453
steiger 0:7c97dcef700c 454 /// Appends the XML node or attribute to a std::string.
steiger 0:7c97dcef700c 455 friend std::string& operator<< (std::string& out, const TiXmlNode& base );
steiger 0:7c97dcef700c 456
steiger 0:7c97dcef700c 457 #endif
steiger 0:7c97dcef700c 458
steiger 0:7c97dcef700c 459 /** The types of XML nodes supported by TinyXml. (All the
steiger 0:7c97dcef700c 460 unsupported types are picked up by UNKNOWN.)
steiger 0:7c97dcef700c 461 */
steiger 0:7c97dcef700c 462 enum NodeType
steiger 0:7c97dcef700c 463 {
steiger 0:7c97dcef700c 464 TINYXML_DOCUMENT,
steiger 0:7c97dcef700c 465 TINYXML_ELEMENT,
steiger 0:7c97dcef700c 466 TINYXML_COMMENT,
steiger 0:7c97dcef700c 467 TINYXML_UNKNOWN,
steiger 0:7c97dcef700c 468 TINYXML_TEXT,
steiger 0:7c97dcef700c 469 TINYXML_DECLARATION,
steiger 0:7c97dcef700c 470 TINYXML_TYPECOUNT
steiger 0:7c97dcef700c 471 };
steiger 0:7c97dcef700c 472
steiger 0:7c97dcef700c 473 virtual ~TiXmlNode();
steiger 0:7c97dcef700c 474
steiger 0:7c97dcef700c 475 /** The meaning of 'value' changes for the specific type of
steiger 0:7c97dcef700c 476 TiXmlNode.
steiger 0:7c97dcef700c 477 @verbatim
steiger 0:7c97dcef700c 478 Document: filename of the xml file
steiger 0:7c97dcef700c 479 Element: name of the element
steiger 0:7c97dcef700c 480 Comment: the comment text
steiger 0:7c97dcef700c 481 Unknown: the tag contents
steiger 0:7c97dcef700c 482 Text: the text string
steiger 0:7c97dcef700c 483 @endverbatim
steiger 0:7c97dcef700c 484
steiger 0:7c97dcef700c 485 The subclasses will wrap this function.
steiger 0:7c97dcef700c 486 */
steiger 0:7c97dcef700c 487 const char *Value() const { return value.c_str (); }
steiger 0:7c97dcef700c 488
steiger 0:7c97dcef700c 489 #ifdef TIXML_USE_STL
steiger 0:7c97dcef700c 490 /** Return Value() as a std::string. If you only use STL,
steiger 0:7c97dcef700c 491 this is more efficient than calling Value().
steiger 0:7c97dcef700c 492 Only available in STL mode.
steiger 0:7c97dcef700c 493 */
steiger 0:7c97dcef700c 494 const std::string& ValueStr() const { return value; }
steiger 0:7c97dcef700c 495 #endif
steiger 0:7c97dcef700c 496
steiger 0:7c97dcef700c 497 const TIXML_STRING& ValueTStr() const { return value; }
steiger 0:7c97dcef700c 498
steiger 0:7c97dcef700c 499 /** Changes the value of the node. Defined as:
steiger 0:7c97dcef700c 500 @verbatim
steiger 0:7c97dcef700c 501 Document: filename of the xml file
steiger 0:7c97dcef700c 502 Element: name of the element
steiger 0:7c97dcef700c 503 Comment: the comment text
steiger 0:7c97dcef700c 504 Unknown: the tag contents
steiger 0:7c97dcef700c 505 Text: the text string
steiger 0:7c97dcef700c 506 @endverbatim
steiger 0:7c97dcef700c 507 */
steiger 0:7c97dcef700c 508 void SetValue(const char * _value) { value = _value;}
steiger 0:7c97dcef700c 509
steiger 0:7c97dcef700c 510 #ifdef TIXML_USE_STL
steiger 0:7c97dcef700c 511 /// STL std::string form.
steiger 0:7c97dcef700c 512 void SetValue( const std::string& _value ) { value = _value; }
steiger 0:7c97dcef700c 513 #endif
steiger 0:7c97dcef700c 514
steiger 0:7c97dcef700c 515 /// Delete all the children of this node. Does not affect 'this'.
steiger 0:7c97dcef700c 516 void Clear();
steiger 0:7c97dcef700c 517
steiger 0:7c97dcef700c 518 /// One step up the DOM.
steiger 0:7c97dcef700c 519 TiXmlNode* Parent() { return parent; }
steiger 0:7c97dcef700c 520 const TiXmlNode* Parent() const { return parent; }
steiger 0:7c97dcef700c 521
steiger 0:7c97dcef700c 522 const TiXmlNode* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children.
steiger 0:7c97dcef700c 523 TiXmlNode* FirstChild() { return firstChild; }
steiger 0:7c97dcef700c 524 const TiXmlNode* FirstChild( const char * value ) const; ///< The first child of this node with the matching 'value'. Will be null if none found.
steiger 0:7c97dcef700c 525 /// The first child of this node with the matching 'value'. Will be null if none found.
steiger 0:7c97dcef700c 526 TiXmlNode* FirstChild( const char * _value ) {
steiger 0:7c97dcef700c 527 // Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe)
steiger 0:7c97dcef700c 528 // call the method, cast the return back to non-const.
steiger 0:7c97dcef700c 529 return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value ));
steiger 0:7c97dcef700c 530 }
steiger 0:7c97dcef700c 531 const TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children.
steiger 0:7c97dcef700c 532 TiXmlNode* LastChild() { return lastChild; }
steiger 0:7c97dcef700c 533
steiger 0:7c97dcef700c 534 const TiXmlNode* LastChild( const char * value ) const; /// The last child of this node matching 'value'. Will be null if there are no children.
steiger 0:7c97dcef700c 535 TiXmlNode* LastChild( const char * _value ) {
steiger 0:7c97dcef700c 536 return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value ));
steiger 0:7c97dcef700c 537 }
steiger 0:7c97dcef700c 538
steiger 0:7c97dcef700c 539 #ifdef TIXML_USE_STL
steiger 0:7c97dcef700c 540 const TiXmlNode* FirstChild( const std::string& _value ) const { return FirstChild (_value.c_str ()); } ///< STL std::string form.
steiger 0:7c97dcef700c 541 TiXmlNode* FirstChild( const std::string& _value ) { return FirstChild (_value.c_str ()); } ///< STL std::string form.
steiger 0:7c97dcef700c 542 const TiXmlNode* LastChild( const std::string& _value ) const { return LastChild (_value.c_str ()); } ///< STL std::string form.
steiger 0:7c97dcef700c 543 TiXmlNode* LastChild( const std::string& _value ) { return LastChild (_value.c_str ()); } ///< STL std::string form.
steiger 0:7c97dcef700c 544 #endif
steiger 0:7c97dcef700c 545
steiger 0:7c97dcef700c 546 /** An alternate way to walk the children of a node.
steiger 0:7c97dcef700c 547 One way to iterate over nodes is:
steiger 0:7c97dcef700c 548 @verbatim
steiger 0:7c97dcef700c 549 for( child = parent->FirstChild(); child; child = child->NextSibling() )
steiger 0:7c97dcef700c 550 @endverbatim
steiger 0:7c97dcef700c 551
steiger 0:7c97dcef700c 552 IterateChildren does the same thing with the syntax:
steiger 0:7c97dcef700c 553 @verbatim
steiger 0:7c97dcef700c 554 child = 0;
steiger 0:7c97dcef700c 555 while( child = parent->IterateChildren( child ) )
steiger 0:7c97dcef700c 556 @endverbatim
steiger 0:7c97dcef700c 557
steiger 0:7c97dcef700c 558 IterateChildren takes the previous child as input and finds
steiger 0:7c97dcef700c 559 the next one. If the previous child is null, it returns the
steiger 0:7c97dcef700c 560 first. IterateChildren will return null when done.
steiger 0:7c97dcef700c 561 */
steiger 0:7c97dcef700c 562 const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const;
steiger 0:7c97dcef700c 563 TiXmlNode* IterateChildren( const TiXmlNode* previous ) {
steiger 0:7c97dcef700c 564 return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) );
steiger 0:7c97dcef700c 565 }
steiger 0:7c97dcef700c 566
steiger 0:7c97dcef700c 567 /// This flavor of IterateChildren searches for children with a particular 'value'
steiger 0:7c97dcef700c 568 const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const;
steiger 0:7c97dcef700c 569 TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) {
steiger 0:7c97dcef700c 570 return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) );
steiger 0:7c97dcef700c 571 }
steiger 0:7c97dcef700c 572
steiger 0:7c97dcef700c 573 #ifdef TIXML_USE_STL
steiger 0:7c97dcef700c 574 const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form.
steiger 0:7c97dcef700c 575 TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form.
steiger 0:7c97dcef700c 576 #endif
steiger 0:7c97dcef700c 577
steiger 0:7c97dcef700c 578 /** Add a new node related to this. Adds a child past the LastChild.
steiger 0:7c97dcef700c 579 Returns a pointer to the new object or NULL if an error occured.
steiger 0:7c97dcef700c 580 */
steiger 0:7c97dcef700c 581 TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
steiger 0:7c97dcef700c 582
steiger 0:7c97dcef700c 583
steiger 0:7c97dcef700c 584 /** Add a new node related to this. Adds a child past the LastChild.
steiger 0:7c97dcef700c 585
steiger 0:7c97dcef700c 586 NOTE: the node to be added is passed by pointer, and will be
steiger 0:7c97dcef700c 587 henceforth owned (and deleted) by tinyXml. This method is efficient
steiger 0:7c97dcef700c 588 and avoids an extra copy, but should be used with care as it
steiger 0:7c97dcef700c 589 uses a different memory model than the other insert functions.
steiger 0:7c97dcef700c 590
steiger 0:7c97dcef700c 591 @sa InsertEndChild
steiger 0:7c97dcef700c 592 */
steiger 0:7c97dcef700c 593 TiXmlNode* LinkEndChild( TiXmlNode* addThis );
steiger 0:7c97dcef700c 594
steiger 0:7c97dcef700c 595 /** Add a new node related to this. Adds a child before the specified child.
steiger 0:7c97dcef700c 596 Returns a pointer to the new object or NULL if an error occured.
steiger 0:7c97dcef700c 597 */
steiger 0:7c97dcef700c 598 TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
steiger 0:7c97dcef700c 599
steiger 0:7c97dcef700c 600 /** Add a new node related to this. Adds a child after the specified child.
steiger 0:7c97dcef700c 601 Returns a pointer to the new object or NULL if an error occured.
steiger 0:7c97dcef700c 602 */
steiger 0:7c97dcef700c 603 TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis );
steiger 0:7c97dcef700c 604
steiger 0:7c97dcef700c 605 /** Replace a child of this node.
steiger 0:7c97dcef700c 606 Returns a pointer to the new object or NULL if an error occured.
steiger 0:7c97dcef700c 607 */
steiger 0:7c97dcef700c 608 TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
steiger 0:7c97dcef700c 609
steiger 0:7c97dcef700c 610 /// Delete a child of this node.
steiger 0:7c97dcef700c 611 bool RemoveChild( TiXmlNode* removeThis );
steiger 0:7c97dcef700c 612
steiger 0:7c97dcef700c 613 /// Navigate to a sibling node.
steiger 0:7c97dcef700c 614 const TiXmlNode* PreviousSibling() const { return prev; }
steiger 0:7c97dcef700c 615 TiXmlNode* PreviousSibling() { return prev; }
steiger 0:7c97dcef700c 616
steiger 0:7c97dcef700c 617 /// Navigate to a sibling node.
steiger 0:7c97dcef700c 618 const TiXmlNode* PreviousSibling( const char * ) const;
steiger 0:7c97dcef700c 619 TiXmlNode* PreviousSibling( const char *_prev ) {
steiger 0:7c97dcef700c 620 return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) );
steiger 0:7c97dcef700c 621 }
steiger 0:7c97dcef700c 622
steiger 0:7c97dcef700c 623 #ifdef TIXML_USE_STL
steiger 0:7c97dcef700c 624 const TiXmlNode* PreviousSibling( const std::string& _value ) const { return PreviousSibling (_value.c_str ()); } ///< STL std::string form.
steiger 0:7c97dcef700c 625 TiXmlNode* PreviousSibling( const std::string& _value ) { return PreviousSibling (_value.c_str ()); } ///< STL std::string form.
steiger 0:7c97dcef700c 626 const TiXmlNode* NextSibling( const std::string& _value) const { return NextSibling (_value.c_str ()); } ///< STL std::string form.
steiger 0:7c97dcef700c 627 TiXmlNode* NextSibling( const std::string& _value) { return NextSibling (_value.c_str ()); } ///< STL std::string form.
steiger 0:7c97dcef700c 628 #endif
steiger 0:7c97dcef700c 629
steiger 0:7c97dcef700c 630 /// Navigate to a sibling node.
steiger 0:7c97dcef700c 631 const TiXmlNode* NextSibling() const { return next; }
steiger 0:7c97dcef700c 632 TiXmlNode* NextSibling() { return next; }
steiger 0:7c97dcef700c 633
steiger 0:7c97dcef700c 634 /// Navigate to a sibling node with the given 'value'.
steiger 0:7c97dcef700c 635 const TiXmlNode* NextSibling( const char * ) const;
steiger 0:7c97dcef700c 636 TiXmlNode* NextSibling( const char* _next ) {
steiger 0:7c97dcef700c 637 return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) );
steiger 0:7c97dcef700c 638 }
steiger 0:7c97dcef700c 639
steiger 0:7c97dcef700c 640 /** Convenience function to get through elements.
steiger 0:7c97dcef700c 641 Calls NextSibling and ToElement. Will skip all non-Element
steiger 0:7c97dcef700c 642 nodes. Returns 0 if there is not another element.
steiger 0:7c97dcef700c 643 */
steiger 0:7c97dcef700c 644 const TiXmlElement* NextSiblingElement() const;
steiger 0:7c97dcef700c 645 TiXmlElement* NextSiblingElement() {
steiger 0:7c97dcef700c 646 return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() );
steiger 0:7c97dcef700c 647 }
steiger 0:7c97dcef700c 648
steiger 0:7c97dcef700c 649 /** Convenience function to get through elements.
steiger 0:7c97dcef700c 650 Calls NextSibling and ToElement. Will skip all non-Element
steiger 0:7c97dcef700c 651 nodes. Returns 0 if there is not another element.
steiger 0:7c97dcef700c 652 */
steiger 0:7c97dcef700c 653 const TiXmlElement* NextSiblingElement( const char * ) const;
steiger 0:7c97dcef700c 654 TiXmlElement* NextSiblingElement( const char *_next ) {
steiger 0:7c97dcef700c 655 return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) );
steiger 0:7c97dcef700c 656 }
steiger 0:7c97dcef700c 657
steiger 0:7c97dcef700c 658 #ifdef TIXML_USE_STL
steiger 0:7c97dcef700c 659 const TiXmlElement* NextSiblingElement( const std::string& _value) const { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form.
steiger 0:7c97dcef700c 660 TiXmlElement* NextSiblingElement( const std::string& _value) { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form.
steiger 0:7c97dcef700c 661 #endif
steiger 0:7c97dcef700c 662
steiger 0:7c97dcef700c 663 /// Convenience function to get through elements.
steiger 0:7c97dcef700c 664 const TiXmlElement* FirstChildElement() const;
steiger 0:7c97dcef700c 665 TiXmlElement* FirstChildElement() {
steiger 0:7c97dcef700c 666 return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() );
steiger 0:7c97dcef700c 667 }
steiger 0:7c97dcef700c 668
steiger 0:7c97dcef700c 669 /// Convenience function to get through elements.
steiger 0:7c97dcef700c 670 const TiXmlElement* FirstChildElement( const char * _value ) const;
steiger 0:7c97dcef700c 671 TiXmlElement* FirstChildElement( const char * _value ) {
steiger 0:7c97dcef700c 672 return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) );
steiger 0:7c97dcef700c 673 }
steiger 0:7c97dcef700c 674
steiger 0:7c97dcef700c 675 #ifdef TIXML_USE_STL
steiger 0:7c97dcef700c 676 const TiXmlElement* FirstChildElement( const std::string& _value ) const { return FirstChildElement (_value.c_str ()); } ///< STL std::string form.
steiger 0:7c97dcef700c 677 TiXmlElement* FirstChildElement( const std::string& _value ) { return FirstChildElement (_value.c_str ()); } ///< STL std::string form.
steiger 0:7c97dcef700c 678 #endif
steiger 0:7c97dcef700c 679
steiger 0:7c97dcef700c 680 /** Query the type (as an enumerated value, above) of this node.
steiger 0:7c97dcef700c 681 The possible types are: DOCUMENT, ELEMENT, COMMENT,
steiger 0:7c97dcef700c 682 UNKNOWN, TEXT, and DECLARATION.
steiger 0:7c97dcef700c 683 */
steiger 0:7c97dcef700c 684 int Type() const { return type; }
steiger 0:7c97dcef700c 685
steiger 0:7c97dcef700c 686 /** Return a pointer to the Document this node lives in.
steiger 0:7c97dcef700c 687 Returns null if not in a document.
steiger 0:7c97dcef700c 688 */
steiger 0:7c97dcef700c 689 const TiXmlDocument* GetDocument() const;
steiger 0:7c97dcef700c 690 TiXmlDocument* GetDocument() {
steiger 0:7c97dcef700c 691 return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() );
steiger 0:7c97dcef700c 692 }
steiger 0:7c97dcef700c 693
steiger 0:7c97dcef700c 694 /// Returns true if this node has no children.
steiger 0:7c97dcef700c 695 bool NoChildren() const { return !firstChild; }
steiger 0:7c97dcef700c 696
steiger 0:7c97dcef700c 697 virtual const TiXmlDocument* ToDocument() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
steiger 0:7c97dcef700c 698 virtual const TiXmlElement* ToElement() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
steiger 0:7c97dcef700c 699 virtual const TiXmlComment* ToComment() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
steiger 0:7c97dcef700c 700 virtual const TiXmlUnknown* ToUnknown() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
steiger 0:7c97dcef700c 701 virtual const TiXmlText* ToText() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
steiger 0:7c97dcef700c 702 virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
steiger 0:7c97dcef700c 703
steiger 0:7c97dcef700c 704 virtual TiXmlDocument* ToDocument() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
steiger 0:7c97dcef700c 705 virtual TiXmlElement* ToElement() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
steiger 0:7c97dcef700c 706 virtual TiXmlComment* ToComment() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
steiger 0:7c97dcef700c 707 virtual TiXmlUnknown* ToUnknown() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
steiger 0:7c97dcef700c 708 virtual TiXmlText* ToText() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
steiger 0:7c97dcef700c 709 virtual TiXmlDeclaration* ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
steiger 0:7c97dcef700c 710
steiger 0:7c97dcef700c 711 /** Create an exact duplicate of this node and return it. The memory must be deleted
steiger 0:7c97dcef700c 712 by the caller.
steiger 0:7c97dcef700c 713 */
steiger 0:7c97dcef700c 714 virtual TiXmlNode* Clone() const = 0;
steiger 0:7c97dcef700c 715
steiger 0:7c97dcef700c 716 /** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the
steiger 0:7c97dcef700c 717 XML tree will be conditionally visited and the host will be called back
steiger 0:7c97dcef700c 718 via the TiXmlVisitor interface.
steiger 0:7c97dcef700c 719
steiger 0:7c97dcef700c 720 This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse
steiger 0:7c97dcef700c 721 the XML for the callbacks, so the performance of TinyXML is unchanged by using this
steiger 0:7c97dcef700c 722 interface versus any other.)
steiger 0:7c97dcef700c 723
steiger 0:7c97dcef700c 724 The interface has been based on ideas from:
steiger 0:7c97dcef700c 725
steiger 0:7c97dcef700c 726 - http://www.saxproject.org/
steiger 0:7c97dcef700c 727 - http://c2.com/cgi/wiki?HierarchicalVisitorPattern
steiger 0:7c97dcef700c 728
steiger 0:7c97dcef700c 729 Which are both good references for "visiting".
steiger 0:7c97dcef700c 730
steiger 0:7c97dcef700c 731 An example of using Accept():
steiger 0:7c97dcef700c 732 @verbatim
steiger 0:7c97dcef700c 733 TiXmlPrinter printer;
steiger 0:7c97dcef700c 734 tinyxmlDoc.Accept( &printer );
steiger 0:7c97dcef700c 735 const char* xmlcstr = printer.CStr();
steiger 0:7c97dcef700c 736 @endverbatim
steiger 0:7c97dcef700c 737 */
steiger 0:7c97dcef700c 738 virtual bool Accept( TiXmlVisitor* visitor ) const = 0;
steiger 0:7c97dcef700c 739
steiger 0:7c97dcef700c 740 protected:
steiger 0:7c97dcef700c 741 TiXmlNode( NodeType _type );
steiger 0:7c97dcef700c 742
steiger 0:7c97dcef700c 743 // Copy to the allocated object. Shared functionality between Clone, Copy constructor,
steiger 0:7c97dcef700c 744 // and the assignment operator.
steiger 0:7c97dcef700c 745 void CopyTo( TiXmlNode* target ) const;
steiger 0:7c97dcef700c 746
steiger 0:7c97dcef700c 747 #ifdef TIXML_USE_STL
steiger 0:7c97dcef700c 748 // The real work of the input operator.
steiger 0:7c97dcef700c 749 virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0;
steiger 0:7c97dcef700c 750 #endif
steiger 0:7c97dcef700c 751
steiger 0:7c97dcef700c 752 // Figure out what is at *p, and parse it. Returns null if it is not an xml node.
steiger 0:7c97dcef700c 753 TiXmlNode* Identify( const char* start, TiXmlEncoding encoding );
steiger 0:7c97dcef700c 754
steiger 0:7c97dcef700c 755 TiXmlNode* parent;
steiger 0:7c97dcef700c 756 NodeType type;
steiger 0:7c97dcef700c 757
steiger 0:7c97dcef700c 758 TiXmlNode* firstChild;
steiger 0:7c97dcef700c 759 TiXmlNode* lastChild;
steiger 0:7c97dcef700c 760
steiger 0:7c97dcef700c 761 TIXML_STRING value;
steiger 0:7c97dcef700c 762
steiger 0:7c97dcef700c 763 TiXmlNode* prev;
steiger 0:7c97dcef700c 764 TiXmlNode* next;
steiger 0:7c97dcef700c 765
steiger 0:7c97dcef700c 766 private:
steiger 0:7c97dcef700c 767 TiXmlNode( const TiXmlNode& ); // not implemented.
steiger 0:7c97dcef700c 768 void operator=( const TiXmlNode& base ); // not allowed.
steiger 0:7c97dcef700c 769 };
steiger 0:7c97dcef700c 770
steiger 0:7c97dcef700c 771
steiger 0:7c97dcef700c 772 /** An attribute is a name-value pair. Elements have an arbitrary
steiger 0:7c97dcef700c 773 number of attributes, each with a unique name.
steiger 0:7c97dcef700c 774
steiger 0:7c97dcef700c 775 @note The attributes are not TiXmlNodes, since they are not
steiger 0:7c97dcef700c 776 part of the tinyXML document object model. There are other
steiger 0:7c97dcef700c 777 suggested ways to look at this problem.
steiger 0:7c97dcef700c 778 */
steiger 0:7c97dcef700c 779 class TiXmlAttribute : public TiXmlBase
steiger 0:7c97dcef700c 780 {
steiger 0:7c97dcef700c 781 friend class TiXmlAttributeSet;
steiger 0:7c97dcef700c 782
steiger 0:7c97dcef700c 783 public:
steiger 0:7c97dcef700c 784 /// Construct an empty attribute.
steiger 0:7c97dcef700c 785 TiXmlAttribute() : TiXmlBase()
steiger 0:7c97dcef700c 786 {
steiger 0:7c97dcef700c 787 document = 0;
steiger 0:7c97dcef700c 788 prev = next = 0;
steiger 0:7c97dcef700c 789 }
steiger 0:7c97dcef700c 790
steiger 0:7c97dcef700c 791 #ifdef TIXML_USE_STL
steiger 0:7c97dcef700c 792 /// std::string constructor.
steiger 0:7c97dcef700c 793 TiXmlAttribute( const std::string& _name, const std::string& _value )
steiger 0:7c97dcef700c 794 {
steiger 0:7c97dcef700c 795 name = _name;
steiger 0:7c97dcef700c 796 value = _value;
steiger 0:7c97dcef700c 797 document = 0;
steiger 0:7c97dcef700c 798 prev = next = 0;
steiger 0:7c97dcef700c 799 }
steiger 0:7c97dcef700c 800 #endif
steiger 0:7c97dcef700c 801
steiger 0:7c97dcef700c 802 /// Construct an attribute with a name and value.
steiger 0:7c97dcef700c 803 TiXmlAttribute( const char * _name, const char * _value )
steiger 0:7c97dcef700c 804 {
steiger 0:7c97dcef700c 805 name = _name;
steiger 0:7c97dcef700c 806 value = _value;
steiger 0:7c97dcef700c 807 document = 0;
steiger 0:7c97dcef700c 808 prev = next = 0;
steiger 0:7c97dcef700c 809 }
steiger 0:7c97dcef700c 810
steiger 0:7c97dcef700c 811 const char* Name() const { return name.c_str(); } ///< Return the name of this attribute.
steiger 0:7c97dcef700c 812 const char* Value() const { return value.c_str(); } ///< Return the value of this attribute.
steiger 0:7c97dcef700c 813 #ifdef TIXML_USE_STL
steiger 0:7c97dcef700c 814 const std::string& ValueStr() const { return value; } ///< Return the value of this attribute.
steiger 0:7c97dcef700c 815 #endif
steiger 0:7c97dcef700c 816 int IntValue() const; ///< Return the value of this attribute, converted to an integer.
steiger 0:7c97dcef700c 817 double DoubleValue() const; ///< Return the value of this attribute, converted to a double.
steiger 0:7c97dcef700c 818
steiger 0:7c97dcef700c 819 // Get the tinyxml string representation
steiger 0:7c97dcef700c 820 const TIXML_STRING& NameTStr() const { return name; }
steiger 0:7c97dcef700c 821
steiger 0:7c97dcef700c 822 /** QueryIntValue examines the value string. It is an alternative to the
steiger 0:7c97dcef700c 823 IntValue() method with richer error checking.
steiger 0:7c97dcef700c 824 If the value is an integer, it is stored in 'value' and
steiger 0:7c97dcef700c 825 the call returns TIXML_SUCCESS. If it is not
steiger 0:7c97dcef700c 826 an integer, it returns TIXML_WRONG_TYPE.
steiger 0:7c97dcef700c 827
steiger 0:7c97dcef700c 828 A specialized but useful call. Note that for success it returns 0,
steiger 0:7c97dcef700c 829 which is the opposite of almost all other TinyXml calls.
steiger 0:7c97dcef700c 830 */
steiger 0:7c97dcef700c 831 int QueryIntValue( int* _value ) const;
steiger 0:7c97dcef700c 832 /// QueryDoubleValue examines the value string. See QueryIntValue().
steiger 0:7c97dcef700c 833 int QueryDoubleValue( double* _value ) const;
steiger 0:7c97dcef700c 834
steiger 0:7c97dcef700c 835 void SetName( const char* _name ) { name = _name; } ///< Set the name of this attribute.
steiger 0:7c97dcef700c 836 void SetValue( const char* _value ) { value = _value; } ///< Set the value.
steiger 0:7c97dcef700c 837
steiger 0:7c97dcef700c 838 void SetIntValue( int _value ); ///< Set the value from an integer.
steiger 0:7c97dcef700c 839 void SetDoubleValue( double _value ); ///< Set the value from a double.
steiger 0:7c97dcef700c 840
steiger 0:7c97dcef700c 841 #ifdef TIXML_USE_STL
steiger 0:7c97dcef700c 842 /// STL std::string form.
steiger 0:7c97dcef700c 843 void SetName( const std::string& _name ) { name = _name; }
steiger 0:7c97dcef700c 844 /// STL std::string form.
steiger 0:7c97dcef700c 845 void SetValue( const std::string& _value ) { value = _value; }
steiger 0:7c97dcef700c 846 #endif
steiger 0:7c97dcef700c 847
steiger 0:7c97dcef700c 848 /// Get the next sibling attribute in the DOM. Returns null at end.
steiger 0:7c97dcef700c 849 const TiXmlAttribute* Next() const;
steiger 0:7c97dcef700c 850 TiXmlAttribute* Next() {
steiger 0:7c97dcef700c 851 return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() );
steiger 0:7c97dcef700c 852 }
steiger 0:7c97dcef700c 853
steiger 0:7c97dcef700c 854 /// Get the previous sibling attribute in the DOM. Returns null at beginning.
steiger 0:7c97dcef700c 855 const TiXmlAttribute* Previous() const;
steiger 0:7c97dcef700c 856 TiXmlAttribute* Previous() {
steiger 0:7c97dcef700c 857 return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() );
steiger 0:7c97dcef700c 858 }
steiger 0:7c97dcef700c 859
steiger 0:7c97dcef700c 860 bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
steiger 0:7c97dcef700c 861 bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; }
steiger 0:7c97dcef700c 862 bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; }
steiger 0:7c97dcef700c 863
steiger 0:7c97dcef700c 864 /* Attribute parsing starts: first letter of the name
steiger 0:7c97dcef700c 865 returns: the next char after the value end quote
steiger 0:7c97dcef700c 866 */
steiger 0:7c97dcef700c 867 virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
steiger 0:7c97dcef700c 868
steiger 0:7c97dcef700c 869 // Prints this Attribute to a FILE stream.
steiger 0:7c97dcef700c 870 virtual void Print( FILE* cfile, int depth ) const {
steiger 0:7c97dcef700c 871 Print( cfile, depth, 0 );
steiger 0:7c97dcef700c 872 }
steiger 0:7c97dcef700c 873 void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
steiger 0:7c97dcef700c 874
steiger 0:7c97dcef700c 875 // [internal use]
steiger 0:7c97dcef700c 876 // Set the document pointer so the attribute can report errors.
steiger 0:7c97dcef700c 877 void SetDocument( TiXmlDocument* doc ) { document = doc; }
steiger 0:7c97dcef700c 878
steiger 0:7c97dcef700c 879 private:
steiger 0:7c97dcef700c 880 TiXmlAttribute( const TiXmlAttribute& ); // not implemented.
steiger 0:7c97dcef700c 881 void operator=( const TiXmlAttribute& base ); // not allowed.
steiger 0:7c97dcef700c 882
steiger 0:7c97dcef700c 883 TiXmlDocument* document; // A pointer back to a document, for error reporting.
steiger 0:7c97dcef700c 884 TIXML_STRING name;
steiger 0:7c97dcef700c 885 TIXML_STRING value;
steiger 0:7c97dcef700c 886 TiXmlAttribute* prev;
steiger 0:7c97dcef700c 887 TiXmlAttribute* next;
steiger 0:7c97dcef700c 888 };
steiger 0:7c97dcef700c 889
steiger 0:7c97dcef700c 890
steiger 0:7c97dcef700c 891 /* A class used to manage a group of attributes.
steiger 0:7c97dcef700c 892 It is only used internally, both by the ELEMENT and the DECLARATION.
steiger 0:7c97dcef700c 893
steiger 0:7c97dcef700c 894 The set can be changed transparent to the Element and Declaration
steiger 0:7c97dcef700c 895 classes that use it, but NOT transparent to the Attribute
steiger 0:7c97dcef700c 896 which has to implement a next() and previous() method. Which makes
steiger 0:7c97dcef700c 897 it a bit problematic and prevents the use of STL.
steiger 0:7c97dcef700c 898
steiger 0:7c97dcef700c 899 This version is implemented with circular lists because:
steiger 0:7c97dcef700c 900 - I like circular lists
steiger 0:7c97dcef700c 901 - it demonstrates some independence from the (typical) doubly linked list.
steiger 0:7c97dcef700c 902 */
steiger 0:7c97dcef700c 903 class TiXmlAttributeSet
steiger 0:7c97dcef700c 904 {
steiger 0:7c97dcef700c 905 public:
steiger 0:7c97dcef700c 906 TiXmlAttributeSet();
steiger 0:7c97dcef700c 907 ~TiXmlAttributeSet();
steiger 0:7c97dcef700c 908
steiger 0:7c97dcef700c 909 void Add( TiXmlAttribute* attribute );
steiger 0:7c97dcef700c 910 void Remove( TiXmlAttribute* attribute );
steiger 0:7c97dcef700c 911
steiger 0:7c97dcef700c 912 const TiXmlAttribute* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
steiger 0:7c97dcef700c 913 TiXmlAttribute* First() { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
steiger 0:7c97dcef700c 914 const TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
steiger 0:7c97dcef700c 915 TiXmlAttribute* Last() { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
steiger 0:7c97dcef700c 916
steiger 0:7c97dcef700c 917 TiXmlAttribute* Find( const char* _name ) const;
steiger 0:7c97dcef700c 918 TiXmlAttribute* FindOrCreate( const char* _name );
steiger 0:7c97dcef700c 919
steiger 0:7c97dcef700c 920 # ifdef TIXML_USE_STL
steiger 0:7c97dcef700c 921 TiXmlAttribute* Find( const std::string& _name ) const;
steiger 0:7c97dcef700c 922 TiXmlAttribute* FindOrCreate( const std::string& _name );
steiger 0:7c97dcef700c 923 # endif
steiger 0:7c97dcef700c 924
steiger 0:7c97dcef700c 925
steiger 0:7c97dcef700c 926 private:
steiger 0:7c97dcef700c 927 //*ME: Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element),
steiger 0:7c97dcef700c 928 //*ME: this class must be also use a hidden/disabled copy-constructor !!!
steiger 0:7c97dcef700c 929 TiXmlAttributeSet( const TiXmlAttributeSet& ); // not allowed
steiger 0:7c97dcef700c 930 void operator=( const TiXmlAttributeSet& ); // not allowed (as TiXmlAttribute)
steiger 0:7c97dcef700c 931
steiger 0:7c97dcef700c 932 TiXmlAttribute sentinel;
steiger 0:7c97dcef700c 933 };
steiger 0:7c97dcef700c 934
steiger 0:7c97dcef700c 935
steiger 0:7c97dcef700c 936 /** The element is a container class. It has a value, the element name,
steiger 0:7c97dcef700c 937 and can contain other elements, text, comments, and unknowns.
steiger 0:7c97dcef700c 938 Elements also contain an arbitrary number of attributes.
steiger 0:7c97dcef700c 939 */
steiger 0:7c97dcef700c 940 class TiXmlElement : public TiXmlNode
steiger 0:7c97dcef700c 941 {
steiger 0:7c97dcef700c 942 public:
steiger 0:7c97dcef700c 943 /// Construct an element.
steiger 0:7c97dcef700c 944 TiXmlElement (const char * in_value);
steiger 0:7c97dcef700c 945
steiger 0:7c97dcef700c 946 #ifdef TIXML_USE_STL
steiger 0:7c97dcef700c 947 /// std::string constructor.
steiger 0:7c97dcef700c 948 TiXmlElement( const std::string& _value );
steiger 0:7c97dcef700c 949 #endif
steiger 0:7c97dcef700c 950
steiger 0:7c97dcef700c 951 TiXmlElement( const TiXmlElement& );
steiger 0:7c97dcef700c 952
steiger 0:7c97dcef700c 953 void operator=( const TiXmlElement& base );
steiger 0:7c97dcef700c 954
steiger 0:7c97dcef700c 955 virtual ~TiXmlElement();
steiger 0:7c97dcef700c 956
steiger 0:7c97dcef700c 957 /** Given an attribute name, Attribute() returns the value
steiger 0:7c97dcef700c 958 for the attribute of that name, or null if none exists.
steiger 0:7c97dcef700c 959 */
steiger 0:7c97dcef700c 960 const char* Attribute( const char* name ) const;
steiger 0:7c97dcef700c 961
steiger 0:7c97dcef700c 962 /** Given an attribute name, Attribute() returns the value
steiger 0:7c97dcef700c 963 for the attribute of that name, or null if none exists.
steiger 0:7c97dcef700c 964 If the attribute exists and can be converted to an integer,
steiger 0:7c97dcef700c 965 the integer value will be put in the return 'i', if 'i'
steiger 0:7c97dcef700c 966 is non-null.
steiger 0:7c97dcef700c 967 */
steiger 0:7c97dcef700c 968 const char* Attribute( const char* name, int* i ) const;
steiger 0:7c97dcef700c 969
steiger 0:7c97dcef700c 970 /** Given an attribute name, Attribute() returns the value
steiger 0:7c97dcef700c 971 for the attribute of that name, or null if none exists.
steiger 0:7c97dcef700c 972 If the attribute exists and can be converted to an double,
steiger 0:7c97dcef700c 973 the double value will be put in the return 'd', if 'd'
steiger 0:7c97dcef700c 974 is non-null.
steiger 0:7c97dcef700c 975 */
steiger 0:7c97dcef700c 976 const char* Attribute( const char* name, double* d ) const;
steiger 0:7c97dcef700c 977
steiger 0:7c97dcef700c 978 /** QueryIntAttribute examines the attribute - it is an alternative to the
steiger 0:7c97dcef700c 979 Attribute() method with richer error checking.
steiger 0:7c97dcef700c 980 If the attribute is an integer, it is stored in 'value' and
steiger 0:7c97dcef700c 981 the call returns TIXML_SUCCESS. If it is not
steiger 0:7c97dcef700c 982 an integer, it returns TIXML_WRONG_TYPE. If the attribute
steiger 0:7c97dcef700c 983 does not exist, then TIXML_NO_ATTRIBUTE is returned.
steiger 0:7c97dcef700c 984 */
steiger 0:7c97dcef700c 985 int QueryIntAttribute( const char* name, int* _value ) const;
steiger 0:7c97dcef700c 986 /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute().
steiger 0:7c97dcef700c 987 int QueryDoubleAttribute( const char* name, double* _value ) const;
steiger 0:7c97dcef700c 988 /// QueryFloatAttribute examines the attribute - see QueryIntAttribute().
steiger 0:7c97dcef700c 989 int QueryFloatAttribute( const char* name, float* _value ) const {
steiger 0:7c97dcef700c 990 double d;
steiger 0:7c97dcef700c 991 int result = QueryDoubleAttribute( name, &d );
steiger 0:7c97dcef700c 992 if ( result == TIXML_SUCCESS ) {
steiger 0:7c97dcef700c 993 *_value = (float)d;
steiger 0:7c97dcef700c 994 }
steiger 0:7c97dcef700c 995 return result;
steiger 0:7c97dcef700c 996 }
steiger 0:7c97dcef700c 997
steiger 0:7c97dcef700c 998 #ifdef TIXML_USE_STL
steiger 0:7c97dcef700c 999 /// QueryStringAttribute examines the attribute - see QueryIntAttribute().
steiger 0:7c97dcef700c 1000 int QueryStringAttribute( const char* name, std::string* _value ) const {
steiger 0:7c97dcef700c 1001 const char* cstr = Attribute( name );
steiger 0:7c97dcef700c 1002 if ( cstr ) {
steiger 0:7c97dcef700c 1003 *_value = std::string( cstr );
steiger 0:7c97dcef700c 1004 return TIXML_SUCCESS;
steiger 0:7c97dcef700c 1005 }
steiger 0:7c97dcef700c 1006 return TIXML_NO_ATTRIBUTE;
steiger 0:7c97dcef700c 1007 }
steiger 0:7c97dcef700c 1008
steiger 0:7c97dcef700c 1009 /** Template form of the attribute query which will try to read the
steiger 0:7c97dcef700c 1010 attribute into the specified type. Very easy, very powerful, but
steiger 0:7c97dcef700c 1011 be careful to make sure to call this with the correct type.
steiger 0:7c97dcef700c 1012
steiger 0:7c97dcef700c 1013 NOTE: This method doesn't work correctly for 'string' types that contain spaces.
steiger 0:7c97dcef700c 1014
steiger 0:7c97dcef700c 1015 @return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE
steiger 0:7c97dcef700c 1016 */
steiger 0:7c97dcef700c 1017 template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const
steiger 0:7c97dcef700c 1018 {
steiger 0:7c97dcef700c 1019 const TiXmlAttribute* node = attributeSet.Find( name );
steiger 0:7c97dcef700c 1020 if ( !node )
steiger 0:7c97dcef700c 1021 return TIXML_NO_ATTRIBUTE;
steiger 0:7c97dcef700c 1022
steiger 0:7c97dcef700c 1023 std::stringstream sstream( node->ValueStr() );
steiger 0:7c97dcef700c 1024 sstream >> *outValue;
steiger 0:7c97dcef700c 1025 if ( !sstream.fail() )
steiger 0:7c97dcef700c 1026 return TIXML_SUCCESS;
steiger 0:7c97dcef700c 1027 return TIXML_WRONG_TYPE;
steiger 0:7c97dcef700c 1028 }
steiger 0:7c97dcef700c 1029
steiger 0:7c97dcef700c 1030 int QueryValueAttribute( const std::string& name, std::string* outValue ) const
steiger 0:7c97dcef700c 1031 {
steiger 0:7c97dcef700c 1032 const TiXmlAttribute* node = attributeSet.Find( name );
steiger 0:7c97dcef700c 1033 if ( !node )
steiger 0:7c97dcef700c 1034 return TIXML_NO_ATTRIBUTE;
steiger 0:7c97dcef700c 1035 *outValue = node->ValueStr();
steiger 0:7c97dcef700c 1036 return TIXML_SUCCESS;
steiger 0:7c97dcef700c 1037 }
steiger 0:7c97dcef700c 1038 #endif
steiger 0:7c97dcef700c 1039
steiger 0:7c97dcef700c 1040 /** Sets an attribute of name to a given value. The attribute
steiger 0:7c97dcef700c 1041 will be created if it does not exist, or changed if it does.
steiger 0:7c97dcef700c 1042 */
steiger 0:7c97dcef700c 1043 void SetAttribute( const char* name, const char * _value );
steiger 0:7c97dcef700c 1044
steiger 0:7c97dcef700c 1045 #ifdef TIXML_USE_STL
steiger 0:7c97dcef700c 1046 const std::string* Attribute( const std::string& name ) const;
steiger 0:7c97dcef700c 1047 const std::string* Attribute( const std::string& name, int* i ) const;
steiger 0:7c97dcef700c 1048 const std::string* Attribute( const std::string& name, double* d ) const;
steiger 0:7c97dcef700c 1049 int QueryIntAttribute( const std::string& name, int* _value ) const;
steiger 0:7c97dcef700c 1050 int QueryDoubleAttribute( const std::string& name, double* _value ) const;
steiger 0:7c97dcef700c 1051
steiger 0:7c97dcef700c 1052 /// STL std::string form.
steiger 0:7c97dcef700c 1053 void SetAttribute( const std::string& name, const std::string& _value );
steiger 0:7c97dcef700c 1054 ///< STL std::string form.
steiger 0:7c97dcef700c 1055 void SetAttribute( const std::string& name, int _value );
steiger 0:7c97dcef700c 1056 ///< STL std::string form.
steiger 0:7c97dcef700c 1057 void SetDoubleAttribute( const std::string& name, double value );
steiger 0:7c97dcef700c 1058 #endif
steiger 0:7c97dcef700c 1059
steiger 0:7c97dcef700c 1060 /** Sets an attribute of name to a given value. The attribute
steiger 0:7c97dcef700c 1061 will be created if it does not exist, or changed if it does.
steiger 0:7c97dcef700c 1062 */
steiger 0:7c97dcef700c 1063 void SetAttribute( const char * name, int value );
steiger 0:7c97dcef700c 1064
steiger 0:7c97dcef700c 1065 /** Sets an attribute of name to a given value. The attribute
steiger 0:7c97dcef700c 1066 will be created if it does not exist, or changed if it does.
steiger 0:7c97dcef700c 1067 */
steiger 0:7c97dcef700c 1068 void SetDoubleAttribute( const char * name, double value );
steiger 0:7c97dcef700c 1069
steiger 0:7c97dcef700c 1070 /** Deletes an attribute with the given name.
steiger 0:7c97dcef700c 1071 */
steiger 0:7c97dcef700c 1072 void RemoveAttribute( const char * name );
steiger 0:7c97dcef700c 1073 #ifdef TIXML_USE_STL
steiger 0:7c97dcef700c 1074 void RemoveAttribute( const std::string& name ) { RemoveAttribute (name.c_str ()); } ///< STL std::string form.
steiger 0:7c97dcef700c 1075 #endif
steiger 0:7c97dcef700c 1076
steiger 0:7c97dcef700c 1077 const TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); } ///< Access the first attribute in this element.
steiger 0:7c97dcef700c 1078 TiXmlAttribute* FirstAttribute() { return attributeSet.First(); }
steiger 0:7c97dcef700c 1079 const TiXmlAttribute* LastAttribute() const { return attributeSet.Last(); } ///< Access the last attribute in this element.
steiger 0:7c97dcef700c 1080 TiXmlAttribute* LastAttribute() { return attributeSet.Last(); }
steiger 0:7c97dcef700c 1081
steiger 0:7c97dcef700c 1082 /** Convenience function for easy access to the text inside an element. Although easy
steiger 0:7c97dcef700c 1083 and concise, GetText() is limited compared to getting the TiXmlText child
steiger 0:7c97dcef700c 1084 and accessing it directly.
steiger 0:7c97dcef700c 1085
steiger 0:7c97dcef700c 1086 If the first child of 'this' is a TiXmlText, the GetText()
steiger 0:7c97dcef700c 1087 returns the character string of the Text node, else null is returned.
steiger 0:7c97dcef700c 1088
steiger 0:7c97dcef700c 1089 This is a convenient method for getting the text of simple contained text:
steiger 0:7c97dcef700c 1090 @verbatim
steiger 0:7c97dcef700c 1091 <foo>This is text</foo>
steiger 0:7c97dcef700c 1092 const char* str = fooElement->GetText();
steiger 0:7c97dcef700c 1093 @endverbatim
steiger 0:7c97dcef700c 1094
steiger 0:7c97dcef700c 1095 'str' will be a pointer to "This is text".
steiger 0:7c97dcef700c 1096
steiger 0:7c97dcef700c 1097 Note that this function can be misleading. If the element foo was created from
steiger 0:7c97dcef700c 1098 this XML:
steiger 0:7c97dcef700c 1099 @verbatim
steiger 0:7c97dcef700c 1100 <foo><b>This is text</b></foo>
steiger 0:7c97dcef700c 1101 @endverbatim
steiger 0:7c97dcef700c 1102
steiger 0:7c97dcef700c 1103 then the value of str would be null. The first child node isn't a text node, it is
steiger 0:7c97dcef700c 1104 another element. From this XML:
steiger 0:7c97dcef700c 1105 @verbatim
steiger 0:7c97dcef700c 1106 <foo>This is <b>text</b></foo>
steiger 0:7c97dcef700c 1107 @endverbatim
steiger 0:7c97dcef700c 1108 GetText() will return "This is ".
steiger 0:7c97dcef700c 1109
steiger 0:7c97dcef700c 1110 WARNING: GetText() accesses a child node - don't become confused with the
steiger 0:7c97dcef700c 1111 similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are
steiger 0:7c97dcef700c 1112 safe type casts on the referenced node.
steiger 0:7c97dcef700c 1113 */
steiger 0:7c97dcef700c 1114 const char* GetText() const;
steiger 0:7c97dcef700c 1115
steiger 0:7c97dcef700c 1116 /// Creates a new Element and returns it - the returned element is a copy.
steiger 0:7c97dcef700c 1117 virtual TiXmlNode* Clone() const;
steiger 0:7c97dcef700c 1118 // Print the Element to a FILE stream.
steiger 0:7c97dcef700c 1119 virtual void Print( FILE* cfile, int depth ) const;
steiger 0:7c97dcef700c 1120
steiger 0:7c97dcef700c 1121 /* Attribtue parsing starts: next char past '<'
steiger 0:7c97dcef700c 1122 returns: next char past '>'
steiger 0:7c97dcef700c 1123 */
steiger 0:7c97dcef700c 1124 virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
steiger 0:7c97dcef700c 1125
steiger 0:7c97dcef700c 1126 virtual const TiXmlElement* ToElement() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
steiger 0:7c97dcef700c 1127 virtual TiXmlElement* ToElement() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
steiger 0:7c97dcef700c 1128
steiger 0:7c97dcef700c 1129 /** Walk the XML tree visiting this node and all of its children.
steiger 0:7c97dcef700c 1130 */
steiger 0:7c97dcef700c 1131 virtual bool Accept( TiXmlVisitor* visitor ) const;
steiger 0:7c97dcef700c 1132
steiger 0:7c97dcef700c 1133 protected:
steiger 0:7c97dcef700c 1134
steiger 0:7c97dcef700c 1135 void CopyTo( TiXmlElement* target ) const;
steiger 0:7c97dcef700c 1136 void ClearThis(); // like clear, but initializes 'this' object as well
steiger 0:7c97dcef700c 1137
steiger 0:7c97dcef700c 1138 // Used to be public [internal use]
steiger 0:7c97dcef700c 1139 #ifdef TIXML_USE_STL
steiger 0:7c97dcef700c 1140 virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
steiger 0:7c97dcef700c 1141 #endif
steiger 0:7c97dcef700c 1142 /* [internal use]
steiger 0:7c97dcef700c 1143 Reads the "value" of the element -- another element, or text.
steiger 0:7c97dcef700c 1144 This should terminate with the current end tag.
steiger 0:7c97dcef700c 1145 */
steiger 0:7c97dcef700c 1146 const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding );
steiger 0:7c97dcef700c 1147
steiger 0:7c97dcef700c 1148 private:
steiger 0:7c97dcef700c 1149 TiXmlAttributeSet attributeSet;
steiger 0:7c97dcef700c 1150 };
steiger 0:7c97dcef700c 1151
steiger 0:7c97dcef700c 1152
steiger 0:7c97dcef700c 1153 /** An XML comment.
steiger 0:7c97dcef700c 1154 */
steiger 0:7c97dcef700c 1155 class TiXmlComment : public TiXmlNode
steiger 0:7c97dcef700c 1156 {
steiger 0:7c97dcef700c 1157 public:
steiger 0:7c97dcef700c 1158 /// Constructs an empty comment.
steiger 0:7c97dcef700c 1159 TiXmlComment() : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {}
steiger 0:7c97dcef700c 1160 /// Construct a comment from text.
steiger 0:7c97dcef700c 1161 TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {
steiger 0:7c97dcef700c 1162 SetValue( _value );
steiger 0:7c97dcef700c 1163 }
steiger 0:7c97dcef700c 1164 TiXmlComment( const TiXmlComment& );
steiger 0:7c97dcef700c 1165 void operator=( const TiXmlComment& base );
steiger 0:7c97dcef700c 1166
steiger 0:7c97dcef700c 1167 virtual ~TiXmlComment() {}
steiger 0:7c97dcef700c 1168
steiger 0:7c97dcef700c 1169 /// Returns a copy of this Comment.
steiger 0:7c97dcef700c 1170 virtual TiXmlNode* Clone() const;
steiger 0:7c97dcef700c 1171 // Write this Comment to a FILE stream.
steiger 0:7c97dcef700c 1172 virtual void Print( FILE* cfile, int depth ) const;
steiger 0:7c97dcef700c 1173
steiger 0:7c97dcef700c 1174 /* Attribtue parsing starts: at the ! of the !--
steiger 0:7c97dcef700c 1175 returns: next char past '>'
steiger 0:7c97dcef700c 1176 */
steiger 0:7c97dcef700c 1177 virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
steiger 0:7c97dcef700c 1178
steiger 0:7c97dcef700c 1179 virtual const TiXmlComment* ToComment() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
steiger 0:7c97dcef700c 1180 virtual TiXmlComment* ToComment() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
steiger 0:7c97dcef700c 1181
steiger 0:7c97dcef700c 1182 /** Walk the XML tree visiting this node and all of its children.
steiger 0:7c97dcef700c 1183 */
steiger 0:7c97dcef700c 1184 virtual bool Accept( TiXmlVisitor* visitor ) const;
steiger 0:7c97dcef700c 1185
steiger 0:7c97dcef700c 1186 protected:
steiger 0:7c97dcef700c 1187 void CopyTo( TiXmlComment* target ) const;
steiger 0:7c97dcef700c 1188
steiger 0:7c97dcef700c 1189 // used to be public
steiger 0:7c97dcef700c 1190 #ifdef TIXML_USE_STL
steiger 0:7c97dcef700c 1191 virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
steiger 0:7c97dcef700c 1192 #endif
steiger 0:7c97dcef700c 1193 // virtual void StreamOut( TIXML_OSTREAM * out ) const;
steiger 0:7c97dcef700c 1194
steiger 0:7c97dcef700c 1195 private:
steiger 0:7c97dcef700c 1196
steiger 0:7c97dcef700c 1197 };
steiger 0:7c97dcef700c 1198
steiger 0:7c97dcef700c 1199
steiger 0:7c97dcef700c 1200 /** XML text. A text node can have 2 ways to output the next. "normal" output
steiger 0:7c97dcef700c 1201 and CDATA. It will default to the mode it was parsed from the XML file and
steiger 0:7c97dcef700c 1202 you generally want to leave it alone, but you can change the output mode with
steiger 0:7c97dcef700c 1203 SetCDATA() and query it with CDATA().
steiger 0:7c97dcef700c 1204 */
steiger 0:7c97dcef700c 1205 class TiXmlText : public TiXmlNode
steiger 0:7c97dcef700c 1206 {
steiger 0:7c97dcef700c 1207 friend class TiXmlElement;
steiger 0:7c97dcef700c 1208 public:
steiger 0:7c97dcef700c 1209 /** Constructor for text element. By default, it is treated as
steiger 0:7c97dcef700c 1210 normal, encoded text. If you want it be output as a CDATA text
steiger 0:7c97dcef700c 1211 element, set the parameter _cdata to 'true'
steiger 0:7c97dcef700c 1212 */
steiger 0:7c97dcef700c 1213 TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT)
steiger 0:7c97dcef700c 1214 {
steiger 0:7c97dcef700c 1215 SetValue( initValue );
steiger 0:7c97dcef700c 1216 cdata = false;
steiger 0:7c97dcef700c 1217 }
steiger 0:7c97dcef700c 1218 virtual ~TiXmlText() {}
steiger 0:7c97dcef700c 1219
steiger 0:7c97dcef700c 1220 #ifdef TIXML_USE_STL
steiger 0:7c97dcef700c 1221 /// Constructor.
steiger 0:7c97dcef700c 1222 TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT)
steiger 0:7c97dcef700c 1223 {
steiger 0:7c97dcef700c 1224 SetValue( initValue );
steiger 0:7c97dcef700c 1225 cdata = false;
steiger 0:7c97dcef700c 1226 }
steiger 0:7c97dcef700c 1227 #endif
steiger 0:7c97dcef700c 1228
steiger 0:7c97dcef700c 1229 TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TINYXML_TEXT ) { copy.CopyTo( this ); }
steiger 0:7c97dcef700c 1230 void operator=( const TiXmlText& base ) { base.CopyTo( this ); }
steiger 0:7c97dcef700c 1231
steiger 0:7c97dcef700c 1232 // Write this text object to a FILE stream.
steiger 0:7c97dcef700c 1233 virtual void Print( FILE* cfile, int depth ) const;
steiger 0:7c97dcef700c 1234
steiger 0:7c97dcef700c 1235 /// Queries whether this represents text using a CDATA section.
steiger 0:7c97dcef700c 1236 bool CDATA() const { return cdata; }
steiger 0:7c97dcef700c 1237 /// Turns on or off a CDATA representation of text.
steiger 0:7c97dcef700c 1238 void SetCDATA( bool _cdata ) { cdata = _cdata; }
steiger 0:7c97dcef700c 1239
steiger 0:7c97dcef700c 1240 virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
steiger 0:7c97dcef700c 1241
steiger 0:7c97dcef700c 1242 virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
steiger 0:7c97dcef700c 1243 virtual TiXmlText* ToText() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
steiger 0:7c97dcef700c 1244
steiger 0:7c97dcef700c 1245 /** Walk the XML tree visiting this node and all of its children.
steiger 0:7c97dcef700c 1246 */
steiger 0:7c97dcef700c 1247 virtual bool Accept( TiXmlVisitor* content ) const;
steiger 0:7c97dcef700c 1248
steiger 0:7c97dcef700c 1249 protected :
steiger 0:7c97dcef700c 1250 /// [internal use] Creates a new Element and returns it.
steiger 0:7c97dcef700c 1251 virtual TiXmlNode* Clone() const;
steiger 0:7c97dcef700c 1252 void CopyTo( TiXmlText* target ) const;
steiger 0:7c97dcef700c 1253
steiger 0:7c97dcef700c 1254 bool Blank() const; // returns true if all white space and new lines
steiger 0:7c97dcef700c 1255 // [internal use]
steiger 0:7c97dcef700c 1256 #ifdef TIXML_USE_STL
steiger 0:7c97dcef700c 1257 virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
steiger 0:7c97dcef700c 1258 #endif
steiger 0:7c97dcef700c 1259
steiger 0:7c97dcef700c 1260 private:
steiger 0:7c97dcef700c 1261 bool cdata; // true if this should be input and output as a CDATA style text element
steiger 0:7c97dcef700c 1262 };
steiger 0:7c97dcef700c 1263
steiger 0:7c97dcef700c 1264
steiger 0:7c97dcef700c 1265 /** In correct XML the declaration is the first entry in the file.
steiger 0:7c97dcef700c 1266 @verbatim
steiger 0:7c97dcef700c 1267 <?xml version="1.0" standalone="yes"?>
steiger 0:7c97dcef700c 1268 @endverbatim
steiger 0:7c97dcef700c 1269
steiger 0:7c97dcef700c 1270 TinyXml will happily read or write files without a declaration,
steiger 0:7c97dcef700c 1271 however. There are 3 possible attributes to the declaration:
steiger 0:7c97dcef700c 1272 version, encoding, and standalone.
steiger 0:7c97dcef700c 1273
steiger 0:7c97dcef700c 1274 Note: In this version of the code, the attributes are
steiger 0:7c97dcef700c 1275 handled as special cases, not generic attributes, simply
steiger 0:7c97dcef700c 1276 because there can only be at most 3 and they are always the same.
steiger 0:7c97dcef700c 1277 */
steiger 0:7c97dcef700c 1278 class TiXmlDeclaration : public TiXmlNode
steiger 0:7c97dcef700c 1279 {
steiger 0:7c97dcef700c 1280 public:
steiger 0:7c97dcef700c 1281 /// Construct an empty declaration.
steiger 0:7c97dcef700c 1282 TiXmlDeclaration() : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) {}
steiger 0:7c97dcef700c 1283
steiger 0:7c97dcef700c 1284 #ifdef TIXML_USE_STL
steiger 0:7c97dcef700c 1285 /// Constructor.
steiger 0:7c97dcef700c 1286 TiXmlDeclaration( const std::string& _version,
steiger 0:7c97dcef700c 1287 const std::string& _encoding,
steiger 0:7c97dcef700c 1288 const std::string& _standalone );
steiger 0:7c97dcef700c 1289 #endif
steiger 0:7c97dcef700c 1290
steiger 0:7c97dcef700c 1291 /// Construct.
steiger 0:7c97dcef700c 1292 TiXmlDeclaration( const char* _version,
steiger 0:7c97dcef700c 1293 const char* _encoding,
steiger 0:7c97dcef700c 1294 const char* _standalone );
steiger 0:7c97dcef700c 1295
steiger 0:7c97dcef700c 1296 TiXmlDeclaration( const TiXmlDeclaration& copy );
steiger 0:7c97dcef700c 1297 void operator=( const TiXmlDeclaration& copy );
steiger 0:7c97dcef700c 1298
steiger 0:7c97dcef700c 1299 virtual ~TiXmlDeclaration() {}
steiger 0:7c97dcef700c 1300
steiger 0:7c97dcef700c 1301 /// Version. Will return an empty string if none was found.
steiger 0:7c97dcef700c 1302 const char *Version() const { return version.c_str (); }
steiger 0:7c97dcef700c 1303 /// Encoding. Will return an empty string if none was found.
steiger 0:7c97dcef700c 1304 const char *Encoding() const { return encoding.c_str (); }
steiger 0:7c97dcef700c 1305 /// Is this a standalone document?
steiger 0:7c97dcef700c 1306 const char *Standalone() const { return standalone.c_str (); }
steiger 0:7c97dcef700c 1307
steiger 0:7c97dcef700c 1308 /// Creates a copy of this Declaration and returns it.
steiger 0:7c97dcef700c 1309 virtual TiXmlNode* Clone() const;
steiger 0:7c97dcef700c 1310 // Print this declaration to a FILE stream.
steiger 0:7c97dcef700c 1311 virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
steiger 0:7c97dcef700c 1312 virtual void Print( FILE* cfile, int depth ) const {
steiger 0:7c97dcef700c 1313 Print( cfile, depth, 0 );
steiger 0:7c97dcef700c 1314 }
steiger 0:7c97dcef700c 1315
steiger 0:7c97dcef700c 1316 virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
steiger 0:7c97dcef700c 1317
steiger 0:7c97dcef700c 1318 virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
steiger 0:7c97dcef700c 1319 virtual TiXmlDeclaration* ToDeclaration() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
steiger 0:7c97dcef700c 1320
steiger 0:7c97dcef700c 1321 /** Walk the XML tree visiting this node and all of its children.
steiger 0:7c97dcef700c 1322 */
steiger 0:7c97dcef700c 1323 virtual bool Accept( TiXmlVisitor* visitor ) const;
steiger 0:7c97dcef700c 1324
steiger 0:7c97dcef700c 1325 protected:
steiger 0:7c97dcef700c 1326 void CopyTo( TiXmlDeclaration* target ) const;
steiger 0:7c97dcef700c 1327 // used to be public
steiger 0:7c97dcef700c 1328 #ifdef TIXML_USE_STL
steiger 0:7c97dcef700c 1329 virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
steiger 0:7c97dcef700c 1330 #endif
steiger 0:7c97dcef700c 1331
steiger 0:7c97dcef700c 1332 private:
steiger 0:7c97dcef700c 1333
steiger 0:7c97dcef700c 1334 TIXML_STRING version;
steiger 0:7c97dcef700c 1335 TIXML_STRING encoding;
steiger 0:7c97dcef700c 1336 TIXML_STRING standalone;
steiger 0:7c97dcef700c 1337 };
steiger 0:7c97dcef700c 1338
steiger 0:7c97dcef700c 1339
steiger 0:7c97dcef700c 1340 /** Any tag that tinyXml doesn't recognize is saved as an
steiger 0:7c97dcef700c 1341 unknown. It is a tag of text, but should not be modified.
steiger 0:7c97dcef700c 1342 It will be written back to the XML, unchanged, when the file
steiger 0:7c97dcef700c 1343 is saved.
steiger 0:7c97dcef700c 1344
steiger 0:7c97dcef700c 1345 DTD tags get thrown into TiXmlUnknowns.
steiger 0:7c97dcef700c 1346 */
steiger 0:7c97dcef700c 1347 class TiXmlUnknown : public TiXmlNode
steiger 0:7c97dcef700c 1348 {
steiger 0:7c97dcef700c 1349 public:
steiger 0:7c97dcef700c 1350 TiXmlUnknown() : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN ) {}
steiger 0:7c97dcef700c 1351 virtual ~TiXmlUnknown() {}
steiger 0:7c97dcef700c 1352
steiger 0:7c97dcef700c 1353 TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN ) { copy.CopyTo( this ); }
steiger 0:7c97dcef700c 1354 void operator=( const TiXmlUnknown& copy ) { copy.CopyTo( this ); }
steiger 0:7c97dcef700c 1355
steiger 0:7c97dcef700c 1356 /// Creates a copy of this Unknown and returns it.
steiger 0:7c97dcef700c 1357 virtual TiXmlNode* Clone() const;
steiger 0:7c97dcef700c 1358 // Print this Unknown to a FILE stream.
steiger 0:7c97dcef700c 1359 virtual void Print( FILE* cfile, int depth ) const;
steiger 0:7c97dcef700c 1360
steiger 0:7c97dcef700c 1361 virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
steiger 0:7c97dcef700c 1362
steiger 0:7c97dcef700c 1363 virtual const TiXmlUnknown* ToUnknown() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
steiger 0:7c97dcef700c 1364 virtual TiXmlUnknown* ToUnknown() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
steiger 0:7c97dcef700c 1365
steiger 0:7c97dcef700c 1366 /** Walk the XML tree visiting this node and all of its children.
steiger 0:7c97dcef700c 1367 */
steiger 0:7c97dcef700c 1368 virtual bool Accept( TiXmlVisitor* content ) const;
steiger 0:7c97dcef700c 1369
steiger 0:7c97dcef700c 1370 protected:
steiger 0:7c97dcef700c 1371 void CopyTo( TiXmlUnknown* target ) const;
steiger 0:7c97dcef700c 1372
steiger 0:7c97dcef700c 1373 #ifdef TIXML_USE_STL
steiger 0:7c97dcef700c 1374 virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
steiger 0:7c97dcef700c 1375 #endif
steiger 0:7c97dcef700c 1376
steiger 0:7c97dcef700c 1377 private:
steiger 0:7c97dcef700c 1378
steiger 0:7c97dcef700c 1379 };
steiger 0:7c97dcef700c 1380
steiger 0:7c97dcef700c 1381
steiger 0:7c97dcef700c 1382 /** Always the top level node. A document binds together all the
steiger 0:7c97dcef700c 1383 XML pieces. It can be saved, loaded, and printed to the screen.
steiger 0:7c97dcef700c 1384 The 'value' of a document node is the xml file name.
steiger 0:7c97dcef700c 1385 */
steiger 0:7c97dcef700c 1386 class TiXmlDocument : public TiXmlNode
steiger 0:7c97dcef700c 1387 {
steiger 0:7c97dcef700c 1388 public:
steiger 0:7c97dcef700c 1389 /// Create an empty document, that has no name.
steiger 0:7c97dcef700c 1390 TiXmlDocument();
steiger 0:7c97dcef700c 1391 /// Create a document with a name. The name of the document is also the filename of the xml.
steiger 0:7c97dcef700c 1392 TiXmlDocument( const char * documentName );
steiger 0:7c97dcef700c 1393
steiger 0:7c97dcef700c 1394 #ifdef TIXML_USE_STL
steiger 0:7c97dcef700c 1395 /// Constructor.
steiger 0:7c97dcef700c 1396 TiXmlDocument( const std::string& documentName );
steiger 0:7c97dcef700c 1397 #endif
steiger 0:7c97dcef700c 1398
steiger 0:7c97dcef700c 1399 TiXmlDocument( const TiXmlDocument& copy );
steiger 0:7c97dcef700c 1400 void operator=( const TiXmlDocument& copy );
steiger 0:7c97dcef700c 1401
steiger 0:7c97dcef700c 1402 virtual ~TiXmlDocument() {}
steiger 0:7c97dcef700c 1403
steiger 0:7c97dcef700c 1404 /** Load a file using the current document value.
steiger 0:7c97dcef700c 1405 Returns true if successful. Will delete any existing
steiger 0:7c97dcef700c 1406 document data before loading.
steiger 0:7c97dcef700c 1407 */
steiger 0:7c97dcef700c 1408 bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
steiger 0:7c97dcef700c 1409 /// Save a file using the current document value. Returns true if successful.
steiger 0:7c97dcef700c 1410 bool SaveFile() const;
steiger 0:7c97dcef700c 1411 /// Load a file using the given filename. Returns true if successful.
steiger 0:7c97dcef700c 1412 bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
steiger 0:7c97dcef700c 1413 /// Save a file using the given filename. Returns true if successful.
steiger 0:7c97dcef700c 1414 bool SaveFile( const char * filename ) const;
steiger 0:7c97dcef700c 1415 /** Load a file using the given FILE*. Returns true if successful. Note that this method
steiger 0:7c97dcef700c 1416 doesn't stream - the entire object pointed at by the FILE*
steiger 0:7c97dcef700c 1417 will be interpreted as an XML file. TinyXML doesn't stream in XML from the current
steiger 0:7c97dcef700c 1418 file location. Streaming may be added in the future.
steiger 0:7c97dcef700c 1419 */
steiger 0:7c97dcef700c 1420 bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
steiger 0:7c97dcef700c 1421 /// Save a file using the given FILE*. Returns true if successful.
steiger 0:7c97dcef700c 1422 bool SaveFile( FILE* ) const;
steiger 0:7c97dcef700c 1423
steiger 0:7c97dcef700c 1424 #ifdef TIXML_USE_STL
steiger 0:7c97dcef700c 1425 bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ) ///< STL std::string version.
steiger 0:7c97dcef700c 1426 {
steiger 0:7c97dcef700c 1427 return LoadFile( filename.c_str(), encoding );
steiger 0:7c97dcef700c 1428 }
steiger 0:7c97dcef700c 1429 bool SaveFile( const std::string& filename ) const ///< STL std::string version.
steiger 0:7c97dcef700c 1430 {
steiger 0:7c97dcef700c 1431 return SaveFile( filename.c_str() );
steiger 0:7c97dcef700c 1432 }
steiger 0:7c97dcef700c 1433 #endif
steiger 0:7c97dcef700c 1434
steiger 0:7c97dcef700c 1435 /** Parse the given null terminated block of xml data. Passing in an encoding to this
steiger 0:7c97dcef700c 1436 method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml
steiger 0:7c97dcef700c 1437 to use that encoding, regardless of what TinyXml might otherwise try to detect.
steiger 0:7c97dcef700c 1438 */
steiger 0:7c97dcef700c 1439 virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
steiger 0:7c97dcef700c 1440
steiger 0:7c97dcef700c 1441 /** Get the root element -- the only top level element -- of the document.
steiger 0:7c97dcef700c 1442 In well formed XML, there should only be one. TinyXml is tolerant of
steiger 0:7c97dcef700c 1443 multiple elements at the document level.
steiger 0:7c97dcef700c 1444 */
steiger 0:7c97dcef700c 1445 const TiXmlElement* RootElement() const { return FirstChildElement(); }
steiger 0:7c97dcef700c 1446 TiXmlElement* RootElement() { return FirstChildElement(); }
steiger 0:7c97dcef700c 1447
steiger 0:7c97dcef700c 1448 /** If an error occurs, Error will be set to true. Also,
steiger 0:7c97dcef700c 1449 - The ErrorId() will contain the integer identifier of the error (not generally useful)
steiger 0:7c97dcef700c 1450 - The ErrorDesc() method will return the name of the error. (very useful)
steiger 0:7c97dcef700c 1451 - The ErrorRow() and ErrorCol() will return the location of the error (if known)
steiger 0:7c97dcef700c 1452 */
steiger 0:7c97dcef700c 1453 bool Error() const { return error; }
steiger 0:7c97dcef700c 1454
steiger 0:7c97dcef700c 1455 /// Contains a textual (english) description of the error if one occurs.
steiger 0:7c97dcef700c 1456 const char * ErrorDesc() const { return errorDesc.c_str (); }
steiger 0:7c97dcef700c 1457
steiger 0:7c97dcef700c 1458 /** Generally, you probably want the error string ( ErrorDesc() ). But if you
steiger 0:7c97dcef700c 1459 prefer the ErrorId, this function will fetch it.
steiger 0:7c97dcef700c 1460 */
steiger 0:7c97dcef700c 1461 int ErrorId() const { return errorId; }
steiger 0:7c97dcef700c 1462
steiger 0:7c97dcef700c 1463 /** Returns the location (if known) of the error. The first column is column 1,
steiger 0:7c97dcef700c 1464 and the first row is row 1. A value of 0 means the row and column wasn't applicable
steiger 0:7c97dcef700c 1465 (memory errors, for example, have no row/column) or the parser lost the error. (An
steiger 0:7c97dcef700c 1466 error in the error reporting, in that case.)
steiger 0:7c97dcef700c 1467
steiger 0:7c97dcef700c 1468 @sa SetTabSize, Row, Column
steiger 0:7c97dcef700c 1469 */
steiger 0:7c97dcef700c 1470 int ErrorRow() const { return errorLocation.row+1; }
steiger 0:7c97dcef700c 1471 int ErrorCol() const { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow()
steiger 0:7c97dcef700c 1472
steiger 0:7c97dcef700c 1473 /** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol())
steiger 0:7c97dcef700c 1474 to report the correct values for row and column. It does not change the output
steiger 0:7c97dcef700c 1475 or input in any way.
steiger 0:7c97dcef700c 1476
steiger 0:7c97dcef700c 1477 By calling this method, with a tab size
steiger 0:7c97dcef700c 1478 greater than 0, the row and column of each node and attribute is stored
steiger 0:7c97dcef700c 1479 when the file is loaded. Very useful for tracking the DOM back in to
steiger 0:7c97dcef700c 1480 the source file.
steiger 0:7c97dcef700c 1481
steiger 0:7c97dcef700c 1482 The tab size is required for calculating the location of nodes. If not
steiger 0:7c97dcef700c 1483 set, the default of 4 is used. The tabsize is set per document. Setting
steiger 0:7c97dcef700c 1484 the tabsize to 0 disables row/column tracking.
steiger 0:7c97dcef700c 1485
steiger 0:7c97dcef700c 1486 Note that row and column tracking is not supported when using operator>>.
steiger 0:7c97dcef700c 1487
steiger 0:7c97dcef700c 1488 The tab size needs to be enabled before the parse or load. Correct usage:
steiger 0:7c97dcef700c 1489 @verbatim
steiger 0:7c97dcef700c 1490 TiXmlDocument doc;
steiger 0:7c97dcef700c 1491 doc.SetTabSize( 8 );
steiger 0:7c97dcef700c 1492 doc.Load( "myfile.xml" );
steiger 0:7c97dcef700c 1493 @endverbatim
steiger 0:7c97dcef700c 1494
steiger 0:7c97dcef700c 1495 @sa Row, Column
steiger 0:7c97dcef700c 1496 */
steiger 0:7c97dcef700c 1497 void SetTabSize( int _tabsize ) { tabsize = _tabsize; }
steiger 0:7c97dcef700c 1498
steiger 0:7c97dcef700c 1499 int TabSize() const { return tabsize; }
steiger 0:7c97dcef700c 1500
steiger 0:7c97dcef700c 1501 /** If you have handled the error, it can be reset with this call. The error
steiger 0:7c97dcef700c 1502 state is automatically cleared if you Parse a new XML block.
steiger 0:7c97dcef700c 1503 */
steiger 0:7c97dcef700c 1504 void ClearError() { error = false;
steiger 0:7c97dcef700c 1505 errorId = 0;
steiger 0:7c97dcef700c 1506 errorDesc = "";
steiger 0:7c97dcef700c 1507 errorLocation.row = errorLocation.col = 0;
steiger 0:7c97dcef700c 1508 //errorLocation.last = 0;
steiger 0:7c97dcef700c 1509 }
steiger 0:7c97dcef700c 1510
steiger 0:7c97dcef700c 1511 /** Write the document to standard out using formatted printing ("pretty print"). */
steiger 0:7c97dcef700c 1512 void Print() const { Print( stdout, 0 ); }
steiger 0:7c97dcef700c 1513
steiger 0:7c97dcef700c 1514 /* Write the document to a string using formatted printing ("pretty print"). This
steiger 0:7c97dcef700c 1515 will allocate a character array (new char[]) and return it as a pointer. The
steiger 0:7c97dcef700c 1516 calling code pust call delete[] on the return char* to avoid a memory leak.
steiger 0:7c97dcef700c 1517 */
steiger 0:7c97dcef700c 1518 //char* PrintToMemory() const;
steiger 0:7c97dcef700c 1519
steiger 0:7c97dcef700c 1520 /// Print this Document to a FILE stream.
steiger 0:7c97dcef700c 1521 virtual void Print( FILE* cfile, int depth = 0 ) const;
steiger 0:7c97dcef700c 1522 // [internal use]
steiger 0:7c97dcef700c 1523 void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding );
steiger 0:7c97dcef700c 1524
steiger 0:7c97dcef700c 1525 virtual const TiXmlDocument* ToDocument() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
steiger 0:7c97dcef700c 1526 virtual TiXmlDocument* ToDocument() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
steiger 0:7c97dcef700c 1527
steiger 0:7c97dcef700c 1528 /** Walk the XML tree visiting this node and all of its children.
steiger 0:7c97dcef700c 1529 */
steiger 0:7c97dcef700c 1530 virtual bool Accept( TiXmlVisitor* content ) const;
steiger 0:7c97dcef700c 1531
steiger 0:7c97dcef700c 1532 protected :
steiger 0:7c97dcef700c 1533 // [internal use]
steiger 0:7c97dcef700c 1534 virtual TiXmlNode* Clone() const;
steiger 0:7c97dcef700c 1535 #ifdef TIXML_USE_STL
steiger 0:7c97dcef700c 1536 virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
steiger 0:7c97dcef700c 1537 #endif
steiger 0:7c97dcef700c 1538
steiger 0:7c97dcef700c 1539 private:
steiger 0:7c97dcef700c 1540 void CopyTo( TiXmlDocument* target ) const;
steiger 0:7c97dcef700c 1541
steiger 0:7c97dcef700c 1542 bool error;
steiger 0:7c97dcef700c 1543 int errorId;
steiger 0:7c97dcef700c 1544 TIXML_STRING errorDesc;
steiger 0:7c97dcef700c 1545 int tabsize;
steiger 0:7c97dcef700c 1546 TiXmlCursor errorLocation;
steiger 0:7c97dcef700c 1547 bool useMicrosoftBOM; // the UTF-8 BOM were found when read. Note this, and try to write.
steiger 0:7c97dcef700c 1548 };
steiger 0:7c97dcef700c 1549
steiger 0:7c97dcef700c 1550
steiger 0:7c97dcef700c 1551 /**
steiger 0:7c97dcef700c 1552 A TiXmlHandle is a class that wraps a node pointer with null checks; this is
steiger 0:7c97dcef700c 1553 an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml
steiger 0:7c97dcef700c 1554 DOM structure. It is a separate utility class.
steiger 0:7c97dcef700c 1555
steiger 0:7c97dcef700c 1556 Take an example:
steiger 0:7c97dcef700c 1557 @verbatim
steiger 0:7c97dcef700c 1558 <Document>
steiger 0:7c97dcef700c 1559 <Element attributeA = "valueA">
steiger 0:7c97dcef700c 1560 <Child attributeB = "value1" />
steiger 0:7c97dcef700c 1561 <Child attributeB = "value2" />
steiger 0:7c97dcef700c 1562 </Element>
steiger 0:7c97dcef700c 1563 <Document>
steiger 0:7c97dcef700c 1564 @endverbatim
steiger 0:7c97dcef700c 1565
steiger 0:7c97dcef700c 1566 Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very
steiger 0:7c97dcef700c 1567 easy to write a *lot* of code that looks like:
steiger 0:7c97dcef700c 1568
steiger 0:7c97dcef700c 1569 @verbatim
steiger 0:7c97dcef700c 1570 TiXmlElement* root = document.FirstChildElement( "Document" );
steiger 0:7c97dcef700c 1571 if ( root )
steiger 0:7c97dcef700c 1572 {
steiger 0:7c97dcef700c 1573 TiXmlElement* element = root->FirstChildElement( "Element" );
steiger 0:7c97dcef700c 1574 if ( element )
steiger 0:7c97dcef700c 1575 {
steiger 0:7c97dcef700c 1576 TiXmlElement* child = element->FirstChildElement( "Child" );
steiger 0:7c97dcef700c 1577 if ( child )
steiger 0:7c97dcef700c 1578 {
steiger 0:7c97dcef700c 1579 TiXmlElement* child2 = child->NextSiblingElement( "Child" );
steiger 0:7c97dcef700c 1580 if ( child2 )
steiger 0:7c97dcef700c 1581 {
steiger 0:7c97dcef700c 1582 // Finally do something useful.
steiger 0:7c97dcef700c 1583 @endverbatim
steiger 0:7c97dcef700c 1584
steiger 0:7c97dcef700c 1585 And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity
steiger 0:7c97dcef700c 1586 of such code. A TiXmlHandle checks for null pointers so it is perfectly safe
steiger 0:7c97dcef700c 1587 and correct to use:
steiger 0:7c97dcef700c 1588
steiger 0:7c97dcef700c 1589 @verbatim
steiger 0:7c97dcef700c 1590 TiXmlHandle docHandle( &document );
steiger 0:7c97dcef700c 1591 TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement();
steiger 0:7c97dcef700c 1592 if ( child2 )
steiger 0:7c97dcef700c 1593 {
steiger 0:7c97dcef700c 1594 // do something useful
steiger 0:7c97dcef700c 1595 @endverbatim
steiger 0:7c97dcef700c 1596
steiger 0:7c97dcef700c 1597 Which is MUCH more concise and useful.
steiger 0:7c97dcef700c 1598
steiger 0:7c97dcef700c 1599 It is also safe to copy handles - internally they are nothing more than node pointers.
steiger 0:7c97dcef700c 1600 @verbatim
steiger 0:7c97dcef700c 1601 TiXmlHandle handleCopy = handle;
steiger 0:7c97dcef700c 1602 @endverbatim
steiger 0:7c97dcef700c 1603
steiger 0:7c97dcef700c 1604 What they should not be used for is iteration:
steiger 0:7c97dcef700c 1605
steiger 0:7c97dcef700c 1606 @verbatim
steiger 0:7c97dcef700c 1607 int i=0;
steiger 0:7c97dcef700c 1608 while ( true )
steiger 0:7c97dcef700c 1609 {
steiger 0:7c97dcef700c 1610 TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement();
steiger 0:7c97dcef700c 1611 if ( !child )
steiger 0:7c97dcef700c 1612 break;
steiger 0:7c97dcef700c 1613 // do something
steiger 0:7c97dcef700c 1614 ++i;
steiger 0:7c97dcef700c 1615 }
steiger 0:7c97dcef700c 1616 @endverbatim
steiger 0:7c97dcef700c 1617
steiger 0:7c97dcef700c 1618 It seems reasonable, but it is in fact two embedded while loops. The Child method is
steiger 0:7c97dcef700c 1619 a linear walk to find the element, so this code would iterate much more than it needs
steiger 0:7c97dcef700c 1620 to. Instead, prefer:
steiger 0:7c97dcef700c 1621
steiger 0:7c97dcef700c 1622 @verbatim
steiger 0:7c97dcef700c 1623 TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement();
steiger 0:7c97dcef700c 1624
steiger 0:7c97dcef700c 1625 for( child; child; child=child->NextSiblingElement() )
steiger 0:7c97dcef700c 1626 {
steiger 0:7c97dcef700c 1627 // do something
steiger 0:7c97dcef700c 1628 }
steiger 0:7c97dcef700c 1629 @endverbatim
steiger 0:7c97dcef700c 1630 */
steiger 0:7c97dcef700c 1631 class TiXmlHandle
steiger 0:7c97dcef700c 1632 {
steiger 0:7c97dcef700c 1633 public:
steiger 0:7c97dcef700c 1634 /// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
steiger 0:7c97dcef700c 1635 TiXmlHandle( TiXmlNode* _node ) { this->node = _node; }
steiger 0:7c97dcef700c 1636 /// Copy constructor
steiger 0:7c97dcef700c 1637 TiXmlHandle( const TiXmlHandle& ref ) { this->node = ref.node; }
steiger 0:7c97dcef700c 1638 TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; }
steiger 0:7c97dcef700c 1639
steiger 0:7c97dcef700c 1640 /// Return a handle to the first child node.
steiger 0:7c97dcef700c 1641 TiXmlHandle FirstChild() const;
steiger 0:7c97dcef700c 1642 /// Return a handle to the first child node with the given name.
steiger 0:7c97dcef700c 1643 TiXmlHandle FirstChild( const char * value ) const;
steiger 0:7c97dcef700c 1644 /// Return a handle to the first child element.
steiger 0:7c97dcef700c 1645 TiXmlHandle FirstChildElement() const;
steiger 0:7c97dcef700c 1646 /// Return a handle to the first child element with the given name.
steiger 0:7c97dcef700c 1647 TiXmlHandle FirstChildElement( const char * value ) const;
steiger 0:7c97dcef700c 1648
steiger 0:7c97dcef700c 1649 /** Return a handle to the "index" child with the given name.
steiger 0:7c97dcef700c 1650 The first child is 0, the second 1, etc.
steiger 0:7c97dcef700c 1651 */
steiger 0:7c97dcef700c 1652 TiXmlHandle Child( const char* value, int index ) const;
steiger 0:7c97dcef700c 1653 /** Return a handle to the "index" child.
steiger 0:7c97dcef700c 1654 The first child is 0, the second 1, etc.
steiger 0:7c97dcef700c 1655 */
steiger 0:7c97dcef700c 1656 TiXmlHandle Child( int index ) const;
steiger 0:7c97dcef700c 1657 /** Return a handle to the "index" child element with the given name.
steiger 0:7c97dcef700c 1658 The first child element is 0, the second 1, etc. Note that only TiXmlElements
steiger 0:7c97dcef700c 1659 are indexed: other types are not counted.
steiger 0:7c97dcef700c 1660 */
steiger 0:7c97dcef700c 1661 TiXmlHandle ChildElement( const char* value, int index ) const;
steiger 0:7c97dcef700c 1662 /** Return a handle to the "index" child element.
steiger 0:7c97dcef700c 1663 The first child element is 0, the second 1, etc. Note that only TiXmlElements
steiger 0:7c97dcef700c 1664 are indexed: other types are not counted.
steiger 0:7c97dcef700c 1665 */
steiger 0:7c97dcef700c 1666 TiXmlHandle ChildElement( int index ) const;
steiger 0:7c97dcef700c 1667
steiger 0:7c97dcef700c 1668 #ifdef TIXML_USE_STL
steiger 0:7c97dcef700c 1669 TiXmlHandle FirstChild( const std::string& _value ) const { return FirstChild( _value.c_str() ); }
steiger 0:7c97dcef700c 1670 TiXmlHandle FirstChildElement( const std::string& _value ) const { return FirstChildElement( _value.c_str() ); }
steiger 0:7c97dcef700c 1671
steiger 0:7c97dcef700c 1672 TiXmlHandle Child( const std::string& _value, int index ) const { return Child( _value.c_str(), index ); }
steiger 0:7c97dcef700c 1673 TiXmlHandle ChildElement( const std::string& _value, int index ) const { return ChildElement( _value.c_str(), index ); }
steiger 0:7c97dcef700c 1674 #endif
steiger 0:7c97dcef700c 1675
steiger 0:7c97dcef700c 1676 /** Return the handle as a TiXmlNode. This may return null.
steiger 0:7c97dcef700c 1677 */
steiger 0:7c97dcef700c 1678 TiXmlNode* ToNode() const { return node; }
steiger 0:7c97dcef700c 1679 /** Return the handle as a TiXmlElement. This may return null.
steiger 0:7c97dcef700c 1680 */
steiger 0:7c97dcef700c 1681 TiXmlElement* ToElement() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
steiger 0:7c97dcef700c 1682 /** Return the handle as a TiXmlText. This may return null.
steiger 0:7c97dcef700c 1683 */
steiger 0:7c97dcef700c 1684 TiXmlText* ToText() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
steiger 0:7c97dcef700c 1685 /** Return the handle as a TiXmlUnknown. This may return null.
steiger 0:7c97dcef700c 1686 */
steiger 0:7c97dcef700c 1687 TiXmlUnknown* ToUnknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
steiger 0:7c97dcef700c 1688
steiger 0:7c97dcef700c 1689 /** @deprecated use ToNode.
steiger 0:7c97dcef700c 1690 Return the handle as a TiXmlNode. This may return null.
steiger 0:7c97dcef700c 1691 */
steiger 0:7c97dcef700c 1692 TiXmlNode* Node() const { return ToNode(); }
steiger 0:7c97dcef700c 1693 /** @deprecated use ToElement.
steiger 0:7c97dcef700c 1694 Return the handle as a TiXmlElement. This may return null.
steiger 0:7c97dcef700c 1695 */
steiger 0:7c97dcef700c 1696 TiXmlElement* Element() const { return ToElement(); }
steiger 0:7c97dcef700c 1697 /** @deprecated use ToText()
steiger 0:7c97dcef700c 1698 Return the handle as a TiXmlText. This may return null.
steiger 0:7c97dcef700c 1699 */
steiger 0:7c97dcef700c 1700 TiXmlText* Text() const { return ToText(); }
steiger 0:7c97dcef700c 1701 /** @deprecated use ToUnknown()
steiger 0:7c97dcef700c 1702 Return the handle as a TiXmlUnknown. This may return null.
steiger 0:7c97dcef700c 1703 */
steiger 0:7c97dcef700c 1704 TiXmlUnknown* Unknown() const { return ToUnknown(); }
steiger 0:7c97dcef700c 1705
steiger 0:7c97dcef700c 1706 private:
steiger 0:7c97dcef700c 1707 TiXmlNode* node;
steiger 0:7c97dcef700c 1708 };
steiger 0:7c97dcef700c 1709
steiger 0:7c97dcef700c 1710
steiger 0:7c97dcef700c 1711 /** Print to memory functionality. The TiXmlPrinter is useful when you need to:
steiger 0:7c97dcef700c 1712
steiger 0:7c97dcef700c 1713 -# Print to memory (especially in non-STL mode)
steiger 0:7c97dcef700c 1714 -# Control formatting (line endings, etc.)
steiger 0:7c97dcef700c 1715
steiger 0:7c97dcef700c 1716 When constructed, the TiXmlPrinter is in its default "pretty printing" mode.
steiger 0:7c97dcef700c 1717 Before calling Accept() you can call methods to control the printing
steiger 0:7c97dcef700c 1718 of the XML document. After TiXmlNode::Accept() is called, the printed document can
steiger 0:7c97dcef700c 1719 be accessed via the CStr(), Str(), and Size() methods.
steiger 0:7c97dcef700c 1720
steiger 0:7c97dcef700c 1721 TiXmlPrinter uses the Visitor API.
steiger 0:7c97dcef700c 1722 @verbatim
steiger 0:7c97dcef700c 1723 TiXmlPrinter printer;
steiger 0:7c97dcef700c 1724 printer.SetIndent( "\t" );
steiger 0:7c97dcef700c 1725
steiger 0:7c97dcef700c 1726 doc.Accept( &printer );
steiger 0:7c97dcef700c 1727 fprintf( stdout, "%s", printer.CStr() );
steiger 0:7c97dcef700c 1728 @endverbatim
steiger 0:7c97dcef700c 1729 */
steiger 0:7c97dcef700c 1730 class TiXmlPrinter : public TiXmlVisitor
steiger 0:7c97dcef700c 1731 {
steiger 0:7c97dcef700c 1732 public:
steiger 0:7c97dcef700c 1733 TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ),
steiger 0:7c97dcef700c 1734 buffer(), indent( " " ), lineBreak( "\n" ) {}
steiger 0:7c97dcef700c 1735
steiger 0:7c97dcef700c 1736 virtual bool VisitEnter( const TiXmlDocument& doc );
steiger 0:7c97dcef700c 1737 virtual bool VisitExit( const TiXmlDocument& doc );
steiger 0:7c97dcef700c 1738
steiger 0:7c97dcef700c 1739 virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute );
steiger 0:7c97dcef700c 1740 virtual bool VisitExit( const TiXmlElement& element );
steiger 0:7c97dcef700c 1741
steiger 0:7c97dcef700c 1742 virtual bool Visit( const TiXmlDeclaration& declaration );
steiger 0:7c97dcef700c 1743 virtual bool Visit( const TiXmlText& text );
steiger 0:7c97dcef700c 1744 virtual bool Visit( const TiXmlComment& comment );
steiger 0:7c97dcef700c 1745 virtual bool Visit( const TiXmlUnknown& unknown );
steiger 0:7c97dcef700c 1746
steiger 0:7c97dcef700c 1747 /** Set the indent characters for printing. By default 4 spaces
steiger 0:7c97dcef700c 1748 but tab (\t) is also useful, or null/empty string for no indentation.
steiger 0:7c97dcef700c 1749 */
steiger 0:7c97dcef700c 1750 void SetIndent( const char* _indent ) { indent = _indent ? _indent : "" ; }
steiger 0:7c97dcef700c 1751 /// Query the indention string.
steiger 0:7c97dcef700c 1752 const char* Indent() { return indent.c_str(); }
steiger 0:7c97dcef700c 1753 /** Set the line breaking string. By default set to newline (\n).
steiger 0:7c97dcef700c 1754 Some operating systems prefer other characters, or can be
steiger 0:7c97dcef700c 1755 set to the null/empty string for no indenation.
steiger 0:7c97dcef700c 1756 */
steiger 0:7c97dcef700c 1757 void SetLineBreak( const char* _lineBreak ) { lineBreak = _lineBreak ? _lineBreak : ""; }
steiger 0:7c97dcef700c 1758 /// Query the current line breaking string.
steiger 0:7c97dcef700c 1759 const char* LineBreak() { return lineBreak.c_str(); }
steiger 0:7c97dcef700c 1760
steiger 0:7c97dcef700c 1761 /** Switch over to "stream printing" which is the most dense formatting without
steiger 0:7c97dcef700c 1762 linebreaks. Common when the XML is needed for network transmission.
steiger 0:7c97dcef700c 1763 */
steiger 0:7c97dcef700c 1764 void SetStreamPrinting() { indent = "";
steiger 0:7c97dcef700c 1765 lineBreak = "";
steiger 0:7c97dcef700c 1766 }
steiger 0:7c97dcef700c 1767 /// Return the result.
steiger 0:7c97dcef700c 1768 const char* CStr() { return buffer.c_str(); }
steiger 0:7c97dcef700c 1769 /// Return the length of the result string.
steiger 0:7c97dcef700c 1770 size_t Size() { return buffer.size(); }
steiger 0:7c97dcef700c 1771
steiger 0:7c97dcef700c 1772 #ifdef TIXML_USE_STL
steiger 0:7c97dcef700c 1773 /// Return the result.
steiger 0:7c97dcef700c 1774 const std::string& Str() { return buffer; }
steiger 0:7c97dcef700c 1775 #endif
steiger 0:7c97dcef700c 1776
steiger 0:7c97dcef700c 1777 private:
steiger 0:7c97dcef700c 1778 void DoIndent() {
steiger 0:7c97dcef700c 1779 for( int i=0; i<depth; ++i )
steiger 0:7c97dcef700c 1780 buffer += indent;
steiger 0:7c97dcef700c 1781 }
steiger 0:7c97dcef700c 1782 void DoLineBreak() {
steiger 0:7c97dcef700c 1783 buffer += lineBreak;
steiger 0:7c97dcef700c 1784 }
steiger 0:7c97dcef700c 1785
steiger 0:7c97dcef700c 1786 int depth;
steiger 0:7c97dcef700c 1787 bool simpleTextPrint;
steiger 0:7c97dcef700c 1788 TIXML_STRING buffer;
steiger 0:7c97dcef700c 1789 TIXML_STRING indent;
steiger 0:7c97dcef700c 1790 TIXML_STRING lineBreak;
steiger 0:7c97dcef700c 1791 };
steiger 0:7c97dcef700c 1792
steiger 0:7c97dcef700c 1793
steiger 0:7c97dcef700c 1794 #ifdef _MSC_VER
steiger 0:7c97dcef700c 1795 #pragma warning( pop )
steiger 0:7c97dcef700c 1796 #endif
steiger 0:7c97dcef700c 1797
steiger 0:7c97dcef700c 1798 #endif
steiger 0:7c97dcef700c 1799