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