Chameleon

Chameleon Svn Source Tree

Root/branches/xZenu/src/modules/TinyXML/include/tinyxml.h

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

Archive Download this file

Revision: 1313