Chameleon

Chameleon Svn Source Tree

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

Source at commit 1314 created 12 years 8 months ago.
By meklort, Temp hacks for xml parser
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{
385#define tolower(c) (((c)>='A' && c<='Z')?((c) | 0x20):(c))
386if ( encoding == TIXML_ENCODING_UTF8 )
387{
388if ( v < 128 ) return tolower( v );
389return v;
390}
391else
392{
393return tolower( v );
394}
395}
396static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
397
398private:
399TiXmlBase( const TiXmlBase& );// not implemented.
400void operator=( const TiXmlBase& base );// not allowed.
401
402struct Entity
403{
404const char* str;
405unsigned intstrLength;
406char chr;
407};
408enum
409{
410NUM_ENTITY = 5,
411MAX_ENTITY_LENGTH = 6
412
413};
414static Entity entity[ NUM_ENTITY ];
415static bool condenseWhiteSpace;
416};
417
418
419/** The parent class for everything in the Document Object Model.
420(Except for attributes).
421Nodes have siblings, a parent, and children. A node can be
422in a document, or stand on its own. The type of a TiXmlNode
423can be queried, and it can be cast to its more defined type.
424*/
425class TiXmlNode : public TiXmlBase
426{
427friend class TiXmlDocument;
428friend class TiXmlElement;
429
430public:
431#ifdef TIXML_USE_STL
432
433 /** An input stream operator, for every class. Tolerant of newlines and
434 formatting, but doesn't expect them.
435 */
436 friend std::istream& operator >> (std::istream& in, TiXmlNode& base);
437
438 /** An output stream operator, for every class. Note that this outputs
439 without any newlines or formatting, as opposed to Print(), which
440 includes tabs and new lines.
441
442 The operator<< and operator>> are not completely symmetric. Writing
443 a node to a stream is very well defined. You'll get a nice stream
444 of output, without any extra whitespace or newlines.
445
446 But reading is not as well defined. (As it always is.) If you create
447 a TiXmlElement (for example) and read that from an input stream,
448 the text needs to define an element or junk will result. This is
449 true of all input streams, but it's worth keeping in mind.
450
451 A TiXmlDocument will read nodes until it reads a root element, and
452all the children of that root element.
453 */
454 friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base);
455
456/// Appends the XML node or attribute to a std::string.
457friend std::string& operator<< (std::string& out, const TiXmlNode& base );
458
459#endif
460
461/** The types of XML nodes supported by TinyXml. (All the
462unsupported types are picked up by UNKNOWN.)
463*/
464enum NodeType
465{
466TINYXML_DOCUMENT,
467TINYXML_ELEMENT,
468TINYXML_COMMENT,
469TINYXML_UNKNOWN,
470TINYXML_TEXT,
471TINYXML_DECLARATION,
472TINYXML_TYPECOUNT
473};
474
475virtual ~TiXmlNode();
476
477/** The meaning of 'value' changes for the specific type of
478TiXmlNode.
479@verbatim
480Document:filename of the xml file
481Element:name of the element
482Comment:the comment text
483Unknown:the tag contents
484Text:the text string
485@endverbatim
486
487The subclasses will wrap this function.
488*/
489const char *Value() const { return value.c_str (); }
490
491 #ifdef TIXML_USE_STL
492/** Return Value() as a std::string. If you only use STL,
493 this is more efficient than calling Value().
494Only available in STL mode.
495*/
496const std::string& ValueStr() const { return value; }
497#endif
498
499const TIXML_STRING& ValueTStr() const { return value; }
500
501/** Changes the value of the node. Defined as:
502@verbatim
503Document:filename of the xml file
504Element:name of the element
505Comment:the comment text
506Unknown:the tag contents
507Text:the text string
508@endverbatim
509*/
510void SetValue(const char * _value) { value = _value;}
511
512 #ifdef TIXML_USE_STL
513/// STL std::string form.
514void SetValue( const std::string& _value ){ value = _value; }
515#endif
516
517/// Delete all the children of this node. Does not affect 'this'.
518void Clear();
519
520/// One step up the DOM.
521TiXmlNode* Parent(){ return parent; }
522const TiXmlNode* Parent() const{ return parent; }
523
524const TiXmlNode* FirstChild()const{ return firstChild; }///< The first child of this node. Will be null if there are no children.
525TiXmlNode* FirstChild(){ return firstChild; }
526const TiXmlNode* FirstChild( const char * value ) const;///< The first child of this node with the matching 'value'. Will be null if none found.
527/// The first child of this node with the matching 'value'. Will be null if none found.
528TiXmlNode* FirstChild( const char * _value ) {
529// Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe)
530// call the method, cast the return back to non-const.
531return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value ));
532}
533const TiXmlNode* LastChild() const{ return lastChild; }/// The last child of this node. Will be null if there are no children.
534TiXmlNode* LastChild(){ return lastChild; }
535
536const TiXmlNode* LastChild( const char * value ) const;/// The last child of this node matching 'value'. Will be null if there are no children.
537TiXmlNode* LastChild( const char * _value ) {
538return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value ));
539}
540
541 #ifdef TIXML_USE_STL
542const TiXmlNode* FirstChild( const std::string& _value ) const{return FirstChild (_value.c_str ());}///< STL std::string form.
543TiXmlNode* FirstChild( const std::string& _value ){return FirstChild (_value.c_str ());}///< STL std::string form.
544const TiXmlNode* LastChild( const std::string& _value ) const{return LastChild (_value.c_str ());}///< STL std::string form.
545TiXmlNode* LastChild( const std::string& _value ){return LastChild (_value.c_str ());}///< STL std::string form.
546#endif
547
548/** An alternate way to walk the children of a node.
549One way to iterate over nodes is:
550@verbatim
551for( child = parent->FirstChild(); child; child = child->NextSibling() )
552@endverbatim
553
554IterateChildren does the same thing with the syntax:
555@verbatim
556child = 0;
557while( child = parent->IterateChildren( child ) )
558@endverbatim
559
560IterateChildren takes the previous child as input and finds
561the next one. If the previous child is null, it returns the
562first. IterateChildren will return null when done.
563*/
564const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const;
565TiXmlNode* IterateChildren( const TiXmlNode* previous ) {
566return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) );
567}
568
569/// This flavor of IterateChildren searches for children with a particular 'value'
570const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const;
571TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) {
572return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) );
573}
574
575 #ifdef TIXML_USE_STL
576const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const{return IterateChildren (_value.c_str (), previous);}///< STL std::string form.
577TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) {return IterateChildren (_value.c_str (), previous);}///< STL std::string form.
578#endif
579
580/** Add a new node related to this. Adds a child past the LastChild.
581Returns a pointer to the new object or NULL if an error occured.
582*/
583TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
584
585
586/** Add a new node related to this. Adds a child past the LastChild.
587
588NOTE: the node to be added is passed by pointer, and will be
589henceforth owned (and deleted) by tinyXml. This method is efficient
590and avoids an extra copy, but should be used with care as it
591uses a different memory model than the other insert functions.
592
593@sa InsertEndChild
594*/
595TiXmlNode* LinkEndChild( TiXmlNode* addThis );
596
597/** Add a new node related to this. Adds a child before the specified child.
598Returns a pointer to the new object or NULL if an error occured.
599*/
600TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
601
602/** Add a new node related to this. Adds a child after the specified child.
603Returns a pointer to the new object or NULL if an error occured.
604*/
605TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis );
606
607/** Replace a child of this node.
608Returns a pointer to the new object or NULL if an error occured.
609*/
610TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
611
612/// Delete a child of this node.
613bool RemoveChild( TiXmlNode* removeThis );
614
615/// Navigate to a sibling node.
616const TiXmlNode* PreviousSibling() const{ return prev; }
617TiXmlNode* PreviousSibling(){ return prev; }
618
619/// Navigate to a sibling node.
620const TiXmlNode* PreviousSibling( const char * ) const;
621TiXmlNode* PreviousSibling( const char *_prev ) {
622return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) );
623}
624
625 #ifdef TIXML_USE_STL
626const TiXmlNode* PreviousSibling( const std::string& _value ) const{return PreviousSibling (_value.c_str ());}///< STL std::string form.
627TiXmlNode* PreviousSibling( const std::string& _value ) {return PreviousSibling (_value.c_str ());}///< STL std::string form.
628const TiXmlNode* NextSibling( const std::string& _value) const{return NextSibling (_value.c_str ());}///< STL std::string form.
629TiXmlNode* NextSibling( const std::string& _value) {return NextSibling (_value.c_str ());}///< STL std::string form.
630#endif
631
632/// Navigate to a sibling node.
633const TiXmlNode* NextSibling() const{ return next; }
634TiXmlNode* NextSibling(){ return next; }
635
636/// Navigate to a sibling node with the given 'value'.
637const TiXmlNode* NextSibling( const char * ) const;
638TiXmlNode* NextSibling( const char* _next ) {
639return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) );
640}
641
642/** Convenience function to get through elements.
643Calls NextSibling and ToElement. Will skip all non-Element
644nodes. Returns 0 if there is not another element.
645*/
646const TiXmlElement* NextSiblingElement() const;
647TiXmlElement* NextSiblingElement() {
648return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() );
649}
650
651/** Convenience function to get through elements.
652Calls NextSibling and ToElement. Will skip all non-Element
653nodes. Returns 0 if there is not another element.
654*/
655const TiXmlElement* NextSiblingElement( const char * ) const;
656TiXmlElement* NextSiblingElement( const char *_next ) {
657return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) );
658}
659
660 #ifdef TIXML_USE_STL
661const TiXmlElement* NextSiblingElement( const std::string& _value) const{return NextSiblingElement (_value.c_str ());}///< STL std::string form.
662TiXmlElement* NextSiblingElement( const std::string& _value){return NextSiblingElement (_value.c_str ());}///< STL std::string form.
663#endif
664
665/// Convenience function to get through elements.
666const TiXmlElement* FirstChildElement()const;
667TiXmlElement* FirstChildElement() {
668return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() );
669}
670
671/// Convenience function to get through elements.
672const TiXmlElement* FirstChildElement( const char * _value ) const;
673TiXmlElement* FirstChildElement( const char * _value ) {
674return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) );
675}
676
677 #ifdef TIXML_USE_STL
678const TiXmlElement* FirstChildElement( const std::string& _value ) const{return FirstChildElement (_value.c_str ());}///< STL std::string form.
679TiXmlElement* FirstChildElement( const std::string& _value ){return FirstChildElement (_value.c_str ());}///< STL std::string form.
680#endif
681
682/** Query the type (as an enumerated value, above) of this node.
683The possible types are: TINYXML_DOCUMENT, TINYXML_ELEMENT, TINYXML_COMMENT,
684TINYXML_UNKNOWN, TINYXML_TEXT, and TINYXML_DECLARATION.
685*/
686int Type() const{ return type; }
687
688/** Return a pointer to the Document this node lives in.
689Returns null if not in a document.
690*/
691const TiXmlDocument* GetDocument() const;
692TiXmlDocument* GetDocument() {
693return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() );
694}
695
696/// Returns true if this node has no children.
697bool NoChildren() const{ return !firstChild; }
698
699virtual const TiXmlDocument* ToDocument() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
700virtual const TiXmlElement* ToElement() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
701virtual const TiXmlComment* ToComment() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
702virtual const TiXmlUnknown* ToUnknown() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
703virtual const TiXmlText* ToText() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
704virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
705
706virtual TiXmlDocument* ToDocument() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
707virtual TiXmlElement* ToElement() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
708virtual TiXmlComment* ToComment() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
709virtual TiXmlUnknown* ToUnknown() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
710virtual TiXmlText* ToText() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
711virtual TiXmlDeclaration* ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
712
713/** Create an exact duplicate of this node and return it. The memory must be deleted
714by the caller.
715*/
716virtual TiXmlNode* Clone() const = 0;
717
718/** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the
719XML tree will be conditionally visited and the host will be called back
720via the TiXmlVisitor interface.
721
722This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse
723the XML for the callbacks, so the performance of TinyXML is unchanged by using this
724interface versus any other.)
725
726The interface has been based on ideas from:
727
728- http://www.saxproject.org/
729- http://c2.com/cgi/wiki?HierarchicalVisitorPattern
730
731Which are both good references for "visiting".
732
733An example of using Accept():
734@verbatim
735TiXmlPrinter printer;
736tinyxmlDoc.Accept( &printer );
737const char* xmlcstr = printer.CStr();
738@endverbatim
739*/
740virtual bool Accept( TiXmlVisitor* visitor ) const = 0;
741
742protected:
743TiXmlNode( NodeType _type );
744
745// Copy to the allocated object. Shared functionality between Clone, Copy constructor,
746// and the assignment operator.
747void CopyTo( TiXmlNode* target ) const;
748
749#ifdef TIXML_USE_STL
750 // The real work of the input operator.
751virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0;
752#endif
753
754// Figure out what is at *p, and parse it. Returns null if it is not an xml node.
755TiXmlNode* Identify( const char* start, TiXmlEncoding encoding );
756
757TiXmlNode*parent;
758NodeTypetype;
759
760TiXmlNode*firstChild;
761TiXmlNode*lastChild;
762
763TIXML_STRINGvalue;
764
765TiXmlNode*prev;
766TiXmlNode*next;
767
768private:
769TiXmlNode( const TiXmlNode& );// not implemented.
770void operator=( const TiXmlNode& base );// not allowed.
771};
772
773
774/** An attribute is a name-value pair. Elements have an arbitrary
775number of attributes, each with a unique name.
776
777@note The attributes are not TiXmlNodes, since they are not
778 part of the tinyXML document object model. There are other
779 suggested ways to look at this problem.
780*/
781class TiXmlAttribute : public TiXmlBase
782{
783friend class TiXmlAttributeSet;
784
785public:
786/// Construct an empty attribute.
787TiXmlAttribute() : TiXmlBase()
788{
789document = 0;
790prev = next = 0;
791}
792
793#ifdef TIXML_USE_STL
794/// std::string constructor.
795TiXmlAttribute( const std::string& _name, const std::string& _value )
796{
797name = _name;
798value = _value;
799document = 0;
800prev = next = 0;
801}
802#endif
803
804/// Construct an attribute with a name and value.
805TiXmlAttribute( const char * _name, const char * _value )
806{
807name = _name;
808value = _value;
809document = 0;
810prev = next = 0;
811}
812
813const char*Name() const{ return name.c_str(); }///< Return the name of this attribute.
814const char*Value() const{ return value.c_str(); }///< Return the value of this attribute.
815#ifdef TIXML_USE_STL
816const std::string& ValueStr() const{ return value; }///< Return the value of this attribute.
817#endif
818intIntValue() const;///< Return the value of this attribute, converted to an integer.
819doubleDoubleValue() const;///< Return the value of this attribute, converted to a double.
820
821// Get the tinyxml string representation
822const TIXML_STRING& NameTStr() const { return name; }
823
824/** QueryIntValue examines the value string. It is an alternative to the
825IntValue() method with richer error checking.
826If the value is an integer, it is stored in 'value' and
827the call returns TIXML_SUCCESS. If it is not
828an integer, it returns TIXML_WRONG_TYPE.
829
830A specialized but useful call. Note that for success it returns 0,
831which is the opposite of almost all other TinyXml calls.
832*/
833int QueryIntValue( int* _value ) const;
834/// QueryDoubleValue examines the value string. See QueryIntValue().
835int QueryDoubleValue( double* _value ) const;
836
837void SetName( const char* _name ){ name = _name; }///< Set the name of this attribute.
838void SetValue( const char* _value ){ value = _value; }///< Set the value.
839
840void SetIntValue( int _value );///< Set the value from an integer.
841void SetDoubleValue( double _value );///< Set the value from a double.
842
843 #ifdef TIXML_USE_STL
844/// STL std::string form.
845void SetName( const std::string& _name ){ name = _name; }
846/// STL std::string form.
847void SetValue( const std::string& _value ){ value = _value; }
848#endif
849
850/// Get the next sibling attribute in the DOM. Returns null at end.
851const TiXmlAttribute* Next() const;
852TiXmlAttribute* Next() {
853return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() );
854}
855
856/// Get the previous sibling attribute in the DOM. Returns null at beginning.
857const TiXmlAttribute* Previous() const;
858TiXmlAttribute* Previous() {
859return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() );
860}
861
862bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
863bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; }
864bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; }
865
866/*Attribute parsing starts: first letter of the name
867 returns: the next char after the value end quote
868*/
869virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
870
871// Prints this Attribute to a FILE stream.
872virtual void Print( FILE* cfile, int depth ) const {
873Print( cfile, depth, 0 );
874}
875void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
876
877// [internal use]
878// Set the document pointer so the attribute can report errors.
879void SetDocument( TiXmlDocument* doc ){ document = doc; }
880
881private:
882TiXmlAttribute( const TiXmlAttribute& );// not implemented.
883void operator=( const TiXmlAttribute& base );// not allowed.
884
885TiXmlDocument*document;// A pointer back to a document, for error reporting.
886TIXML_STRING name;
887TIXML_STRING value;
888TiXmlAttribute*prev;
889TiXmlAttribute*next;
890};
891
892
893/*A class used to manage a group of attributes.
894It is only used internally, both by the ELEMENT and the DECLARATION.
895
896The set can be changed transparent to the Element and Declaration
897classes that use it, but NOT transparent to the Attribute
898which has to implement a next() and previous() method. Which makes
899it a bit problematic and prevents the use of STL.
900
901This version is implemented with circular lists because:
902- I like circular lists
903- it demonstrates some independence from the (typical) doubly linked list.
904*/
905class TiXmlAttributeSet
906{
907public:
908TiXmlAttributeSet();
909~TiXmlAttributeSet();
910
911void Add( TiXmlAttribute* attribute );
912void Remove( TiXmlAttribute* attribute );
913
914const TiXmlAttribute* First()const{ return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
915TiXmlAttribute* First(){ return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
916const TiXmlAttribute* Last() const{ return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
917TiXmlAttribute* Last(){ return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
918
919TiXmlAttribute*Find( const char* _name ) const;
920TiXmlAttribute* FindOrCreate( const char* _name );
921
922#ifdef TIXML_USE_STL
923TiXmlAttribute*Find( const std::string& _name ) const;
924TiXmlAttribute* FindOrCreate( const std::string& _name );
925#endif
926
927
928private:
929//*ME:Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element),
930//*ME:this class must be also use a hidden/disabled copy-constructor !!!
931TiXmlAttributeSet( const TiXmlAttributeSet& );// not allowed
932void operator=( const TiXmlAttributeSet& );// not allowed (as TiXmlAttribute)
933
934TiXmlAttribute sentinel;
935};
936
937
938/** The element is a container class. It has a value, the element name,
939and can contain other elements, text, comments, and unknowns.
940Elements also contain an arbitrary number of attributes.
941*/
942class TiXmlElement : public TiXmlNode
943{
944public:
945/// Construct an element.
946TiXmlElement (const char * in_value);
947
948#ifdef TIXML_USE_STL
949/// std::string constructor.
950TiXmlElement( const std::string& _value );
951#endif
952
953TiXmlElement( const TiXmlElement& );
954
955TiXmlElement& operator=( const TiXmlElement& base );
956
957virtual ~TiXmlElement();
958
959/** Given an attribute name, Attribute() returns the value
960for the attribute of that name, or null if none exists.
961*/
962const char* Attribute( const char* name ) const;
963
964/** Given an attribute name, Attribute() returns the value
965for the attribute of that name, or null if none exists.
966If the attribute exists and can be converted to an integer,
967the integer value will be put in the return 'i', if 'i'
968is non-null.
969*/
970const char* Attribute( const char* name, int* i ) const;
971
972/** Given an attribute name, Attribute() returns the value
973for the attribute of that name, or null if none exists.
974If the attribute exists and can be converted to an double,
975the double value will be put in the return 'd', if 'd'
976is non-null.
977*/
978const char* Attribute( const char* name, double* d ) const;
979
980/** QueryIntAttribute examines the attribute - it is an alternative to the
981Attribute() method with richer error checking.
982If the attribute is an integer, it is stored in 'value' and
983the call returns TIXML_SUCCESS. If it is not
984an integer, it returns TIXML_WRONG_TYPE. If the attribute
985does not exist, then TIXML_NO_ATTRIBUTE is returned.
986*/
987int QueryIntAttribute( const char* name, int* _value ) const;
988/// QueryUnsignedAttribute examines the attribute - see QueryIntAttribute().
989int QueryUnsignedAttribute( const char* name, unsigned* _value ) const;
990/** QueryBoolAttribute examines the attribute - see QueryIntAttribute().
991Note that '1', 'true', or 'yes' are considered true, while '0', 'false'
992and 'no' are considered false.
993*/
994int QueryBoolAttribute( const char* name, bool* _value ) const;
995/// QueryDoubleAttribute examines the attribute - see QueryIntAttribute().
996int QueryDoubleAttribute( const char* name, double* _value ) const;
997/// QueryFloatAttribute examines the attribute - see QueryIntAttribute().
998int QueryFloatAttribute( const char* name, float* _value ) const {
999double d;
1000int result = QueryDoubleAttribute( name, &d );
1001if ( result == TIXML_SUCCESS ) {
1002*_value = (float)d;
1003}
1004return result;
1005}
1006
1007 #ifdef TIXML_USE_STL
1008/// QueryStringAttribute examines the attribute - see QueryIntAttribute().
1009int QueryStringAttribute( const char* name, std::string* _value ) const {
1010const char* cstr = Attribute( name );
1011if ( cstr ) {
1012*_value = std::string( cstr );
1013return TIXML_SUCCESS;
1014}
1015return TIXML_NO_ATTRIBUTE;
1016}
1017
1018/** Template form of the attribute query which will try to read the
1019attribute into the specified type. Very easy, very powerful, but
1020be careful to make sure to call this with the correct type.
1021
1022NOTE: This method doesn't work correctly for 'string' types that contain spaces.
1023
1024@return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE
1025*/
1026template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const
1027{
1028const TiXmlAttribute* node = attributeSet.Find( name );
1029if ( !node )
1030return TIXML_NO_ATTRIBUTE;
1031
1032std::stringstream sstream( node->ValueStr() );
1033sstream >> *outValue;
1034if ( !sstream.fail() )
1035return TIXML_SUCCESS;
1036return TIXML_WRONG_TYPE;
1037}
1038
1039int QueryValueAttribute( const std::string& name, std::string* outValue ) const
1040{
1041const TiXmlAttribute* node = attributeSet.Find( name );
1042if ( !node )
1043return TIXML_NO_ATTRIBUTE;
1044*outValue = node->ValueStr();
1045return TIXML_SUCCESS;
1046}
1047#endif
1048
1049/** Sets an attribute of name to a given value. The attribute
1050will be created if it does not exist, or changed if it does.
1051*/
1052void SetAttribute( const char* name, const char * _value );
1053
1054 #ifdef TIXML_USE_STL
1055const std::string* Attribute( const std::string& name ) const;
1056const std::string* Attribute( const std::string& name, int* i ) const;
1057const std::string* Attribute( const std::string& name, double* d ) const;
1058int QueryIntAttribute( const std::string& name, int* _value ) const;
1059int QueryDoubleAttribute( const std::string& name, double* _value ) const;
1060
1061/// STL std::string form.
1062void SetAttribute( const std::string& name, const std::string& _value );
1063///< STL std::string form.
1064void SetAttribute( const std::string& name, int _value );
1065///< STL std::string form.
1066void SetDoubleAttribute( const std::string& name, double value );
1067#endif
1068
1069/** Sets an attribute of name to a given value. The attribute
1070will be created if it does not exist, or changed if it does.
1071*/
1072void SetAttribute( const char * name, int value );
1073
1074/** Sets an attribute of name to a given value. The attribute
1075will be created if it does not exist, or changed if it does.
1076*/
1077void SetDoubleAttribute( const char * name, double value );
1078
1079/** Deletes an attribute with the given name.
1080*/
1081void RemoveAttribute( const char * name );
1082 #ifdef TIXML_USE_STL
1083void RemoveAttribute( const std::string& name ){RemoveAttribute (name.c_str ());}///< STL std::string form.
1084#endif
1085
1086const TiXmlAttribute* FirstAttribute() const{ return attributeSet.First(); }///< Access the first attribute in this element.
1087TiXmlAttribute* FirstAttribute() { return attributeSet.First(); }
1088const TiXmlAttribute* LastAttribute()const { return attributeSet.Last(); }///< Access the last attribute in this element.
1089TiXmlAttribute* LastAttribute(){ return attributeSet.Last(); }
1090
1091/** Convenience function for easy access to the text inside an element. Although easy
1092and concise, GetText() is limited compared to getting the TiXmlText child
1093and accessing it directly.
1094
1095If the first child of 'this' is a TiXmlText, the GetText()
1096returns the character string of the Text node, else null is returned.
1097
1098This is a convenient method for getting the text of simple contained text:
1099@verbatim
1100<foo>This is text</foo>
1101const char* str = fooElement->GetText();
1102@endverbatim
1103
1104'str' will be a pointer to "This is text".
1105
1106Note that this function can be misleading. If the element foo was created from
1107this XML:
1108@verbatim
1109<foo><b>This is text</b></foo>
1110@endverbatim
1111
1112then the value of str would be null. The first child node isn't a text node, it is
1113another element. From this XML:
1114@verbatim
1115<foo>This is <b>text</b></foo>
1116@endverbatim
1117GetText() will return "This is ".
1118
1119WARNING: GetText() accesses a child node - don't become confused with the
1120 similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are
1121 safe type casts on the referenced node.
1122*/
1123const char* GetText() const;
1124
1125/// Creates a new Element and returns it - the returned element is a copy.
1126virtual TiXmlNode* Clone() const;
1127// Print the Element to a FILE stream.
1128virtual void Print( FILE* cfile, int depth ) const;
1129
1130/*Attribtue parsing starts: next char past '<'
1131 returns: next char past '>'
1132*/
1133virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
1134
1135virtual const TiXmlElement* ToElement() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1136virtual TiXmlElement* ToElement() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1137
1138/** Walk the XML tree visiting this node and all of its children.
1139*/
1140virtual bool Accept( TiXmlVisitor* visitor ) const;
1141
1142protected:
1143
1144void CopyTo( TiXmlElement* target ) const;
1145void ClearThis();// like clear, but initializes 'this' object as well
1146
1147// Used to be public [internal use]
1148#ifdef TIXML_USE_STL
1149virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
1150#endif
1151/*[internal use]
1152Reads the "value" of the element -- another element, or text.
1153This should terminate with the current end tag.
1154*/
1155const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding );
1156
1157private:
1158TiXmlAttributeSet attributeSet;
1159};
1160
1161
1162/**An XML comment.
1163*/
1164class TiXmlComment : public TiXmlNode
1165{
1166public:
1167/// Constructs an empty comment.
1168TiXmlComment() : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {}
1169/// Construct a comment from text.
1170TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {
1171SetValue( _value );
1172}
1173TiXmlComment( const TiXmlComment& );
1174TiXmlComment& operator=( const TiXmlComment& base );
1175
1176virtual ~TiXmlComment(){}
1177
1178/// Returns a copy of this Comment.
1179virtual TiXmlNode* Clone() const;
1180// Write this Comment to a FILE stream.
1181virtual void Print( FILE* cfile, int depth ) const;
1182
1183/*Attribtue parsing starts: at the ! of the !--
1184 returns: next char past '>'
1185*/
1186virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
1187
1188virtual const TiXmlComment* ToComment() const{ return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1189virtual TiXmlComment* ToComment(){ return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1190
1191/** Walk the XML tree visiting this node and all of its children.
1192*/
1193virtual bool Accept( TiXmlVisitor* visitor ) const;
1194
1195protected:
1196void CopyTo( TiXmlComment* target ) const;
1197
1198// used to be public
1199#ifdef TIXML_USE_STL
1200virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
1201#endif
1202//virtual void StreamOut( TIXML_OSTREAM * out ) const;
1203
1204private:
1205
1206};
1207
1208
1209/** XML text. A text node can have 2 ways to output the next. "normal" output
1210and CDATA. It will default to the mode it was parsed from the XML file and
1211you generally want to leave it alone, but you can change the output mode with
1212SetCDATA() and query it with CDATA().
1213*/
1214class TiXmlText : public TiXmlNode
1215{
1216friend class TiXmlElement;
1217public:
1218/** Constructor for text element. By default, it is treated as
1219normal, encoded text. If you want it be output as a CDATA text
1220element, set the parameter _cdata to 'true'
1221*/
1222TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT)
1223{
1224SetValue( initValue );
1225cdata = false;
1226}
1227virtual ~TiXmlText() {}
1228
1229#ifdef TIXML_USE_STL
1230/// Constructor.
1231TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT)
1232{
1233SetValue( initValue );
1234cdata = false;
1235}
1236#endif
1237
1238TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TINYXML_TEXT ){ copy.CopyTo( this ); }
1239TiXmlText& operator=( const TiXmlText& base ) { base.CopyTo( this ); return *this; }
1240
1241// Write this text object to a FILE stream.
1242virtual void Print( FILE* cfile, int depth ) const;
1243
1244/// Queries whether this represents text using a CDATA section.
1245bool CDATA() const{ return cdata; }
1246/// Turns on or off a CDATA representation of text.
1247void SetCDATA( bool _cdata ){ cdata = _cdata; }
1248
1249virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
1250
1251virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1252virtual TiXmlText* ToText() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1253
1254/** Walk the XML tree visiting this node and all of its children.
1255*/
1256virtual bool Accept( TiXmlVisitor* content ) const;
1257
1258protected :
1259/// [internal use] Creates a new Element and returns it.
1260virtual TiXmlNode* Clone() const;
1261void CopyTo( TiXmlText* target ) const;
1262
1263bool Blank() const;// returns true if all white space and new lines
1264// [internal use]
1265#ifdef TIXML_USE_STL
1266virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
1267#endif
1268
1269private:
1270bool cdata;// true if this should be input and output as a CDATA style text element
1271};
1272
1273
1274/** In correct XML the declaration is the first entry in the file.
1275@verbatim
1276<?xml version="1.0" standalone="yes"?>
1277@endverbatim
1278
1279TinyXml will happily read or write files without a declaration,
1280however. There are 3 possible attributes to the declaration:
1281version, encoding, and standalone.
1282
1283Note: In this version of the code, the attributes are
1284handled as special cases, not generic attributes, simply
1285because there can only be at most 3 and they are always the same.
1286*/
1287class TiXmlDeclaration : public TiXmlNode
1288{
1289public:
1290/// Construct an empty declaration.
1291TiXmlDeclaration() : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) {}
1292
1293#ifdef TIXML_USE_STL
1294/// Constructor.
1295TiXmlDeclaration(const std::string& _version,
1296const std::string& _encoding,
1297const std::string& _standalone );
1298#endif
1299
1300/// Construct.
1301TiXmlDeclaration(const char* _version,
1302const char* _encoding,
1303const char* _standalone );
1304
1305TiXmlDeclaration( const TiXmlDeclaration& copy );
1306TiXmlDeclaration& operator=( const TiXmlDeclaration& copy );
1307
1308virtual ~TiXmlDeclaration(){}
1309
1310/// Version. Will return an empty string if none was found.
1311const char *Version() const{ return version.c_str (); }
1312/// Encoding. Will return an empty string if none was found.
1313const char *Encoding() const{ return encoding.c_str (); }
1314/// Is this a standalone document?
1315const char *Standalone() const{ return standalone.c_str (); }
1316
1317/// Creates a copy of this Declaration and returns it.
1318virtual TiXmlNode* Clone() const;
1319// Print this declaration to a FILE stream.
1320virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
1321virtual void Print( FILE* cfile, int depth ) const {
1322Print( cfile, depth, 0 );
1323}
1324
1325virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
1326
1327virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1328virtual TiXmlDeclaration* ToDeclaration() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1329
1330/** Walk the XML tree visiting this node and all of its children.
1331*/
1332virtual bool Accept( TiXmlVisitor* visitor ) const;
1333
1334protected:
1335void CopyTo( TiXmlDeclaration* target ) const;
1336// used to be public
1337#ifdef TIXML_USE_STL
1338virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
1339#endif
1340
1341private:
1342
1343TIXML_STRING version;
1344TIXML_STRING encoding;
1345TIXML_STRING standalone;
1346};
1347
1348
1349/** Any tag that tinyXml doesn't recognize is saved as an
1350unknown. It is a tag of text, but should not be modified.
1351It will be written back to the XML, unchanged, when the file
1352is saved.
1353
1354DTD tags get thrown into TiXmlUnknowns.
1355*/
1356class TiXmlUnknown : public TiXmlNode
1357{
1358public:
1359TiXmlUnknown() : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN ){}
1360virtual ~TiXmlUnknown() {}
1361
1362TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN ){ copy.CopyTo( this ); }
1363TiXmlUnknown& operator=( const TiXmlUnknown& copy ){ copy.CopyTo( this ); return *this; }
1364
1365/// Creates a copy of this Unknown and returns it.
1366virtual TiXmlNode* Clone() const;
1367// Print this Unknown to a FILE stream.
1368virtual void Print( FILE* cfile, int depth ) const;
1369
1370virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
1371
1372virtual const TiXmlUnknown* ToUnknown() const{ return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1373virtual TiXmlUnknown* ToUnknown(){ return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1374
1375/** Walk the XML tree visiting this node and all of its children.
1376*/
1377virtual bool Accept( TiXmlVisitor* content ) const;
1378
1379protected:
1380void CopyTo( TiXmlUnknown* target ) const;
1381
1382#ifdef TIXML_USE_STL
1383virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
1384#endif
1385
1386private:
1387
1388};
1389
1390
1391/** Always the top level node. A document binds together all the
1392XML pieces. It can be saved, loaded, and printed to the screen.
1393The 'value' of a document node is the xml file name.
1394*/
1395class TiXmlDocument : public TiXmlNode
1396{
1397public:
1398/// Create an empty document, that has no name.
1399TiXmlDocument();
1400/// Create a document with a name. The name of the document is also the filename of the xml.
1401TiXmlDocument( const char * documentName );
1402
1403#ifdef TIXML_USE_STL
1404/// Constructor.
1405TiXmlDocument( const std::string& documentName );
1406#endif
1407
1408TiXmlDocument( const TiXmlDocument& copy );
1409TiXmlDocument& operator=( const TiXmlDocument& copy );
1410
1411virtual ~TiXmlDocument() {}
1412
1413/** Load a file using the current document value.
1414Returns true if successful. Will delete any existing
1415document data before loading.
1416*/
1417bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1418/// Save a file using the current document value. Returns true if successful.
1419bool SaveFile() const;
1420/// Load a file using the given filename. Returns true if successful.
1421bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1422/// Save a file using the given filename. Returns true if successful.
1423bool SaveFile( const char * filename ) const;
1424/** Load a file using the given FILE*. Returns true if successful. Note that this method
1425doesn't stream - the entire object pointed at by the FILE*
1426will be interpreted as an XML file. TinyXML doesn't stream in XML from the current
1427file location. Streaming may be added in the future.
1428*/
1429bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1430/// Save a file using the given FILE*. Returns true if successful.
1431bool SaveFile( FILE* ) const;
1432
1433#ifdef TIXML_USE_STL
1434bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING )///< STL std::string version.
1435{
1436return LoadFile( filename.c_str(), encoding );
1437}
1438bool SaveFile( const std::string& filename ) const///< STL std::string version.
1439{
1440return SaveFile( filename.c_str() );
1441}
1442#endif
1443
1444/** Parse the given null terminated block of xml data. Passing in an encoding to this
1445method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml
1446to use that encoding, regardless of what TinyXml might otherwise try to detect.
1447*/
1448virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1449
1450/** Get the root element -- the only top level element -- of the document.
1451In well formed XML, there should only be one. TinyXml is tolerant of
1452multiple elements at the document level.
1453*/
1454const TiXmlElement* RootElement() const{ return FirstChildElement(); }
1455TiXmlElement* RootElement(){ return FirstChildElement(); }
1456
1457/** If an error occurs, Error will be set to true. Also,
1458- The ErrorId() will contain the integer identifier of the error (not generally useful)
1459- The ErrorDesc() method will return the name of the error. (very useful)
1460- The ErrorRow() and ErrorCol() will return the location of the error (if known)
1461*/
1462bool Error() const{ return error; }
1463
1464/// Contains a textual (english) description of the error if one occurs.
1465const char * ErrorDesc() const{ return errorDesc.c_str (); }
1466
1467/** Generally, you probably want the error string ( ErrorDesc() ). But if you
1468prefer the ErrorId, this function will fetch it.
1469*/
1470int ErrorId()const{ return errorId; }
1471
1472/** Returns the location (if known) of the error. The first column is column 1,
1473and the first row is row 1. A value of 0 means the row and column wasn't applicable
1474(memory errors, for example, have no row/column) or the parser lost the error. (An
1475error in the error reporting, in that case.)
1476
1477@sa SetTabSize, Row, Column
1478*/
1479int ErrorRow() const{ return errorLocation.row+1; }
1480int ErrorCol() const{ return errorLocation.col+1; }///< The column where the error occured. See ErrorRow()
1481
1482/** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol())
1483to report the correct values for row and column. It does not change the output
1484or input in any way.
1485
1486By calling this method, with a tab size
1487greater than 0, the row and column of each node and attribute is stored
1488when the file is loaded. Very useful for tracking the DOM back in to
1489the source file.
1490
1491The tab size is required for calculating the location of nodes. If not
1492set, the default of 4 is used. The tabsize is set per document. Setting
1493the tabsize to 0 disables row/column tracking.
1494
1495Note that row and column tracking is not supported when using operator>>.
1496
1497The tab size needs to be enabled before the parse or load. Correct usage:
1498@verbatim
1499TiXmlDocument doc;
1500doc.SetTabSize( 8 );
1501doc.Load( "myfile.xml" );
1502@endverbatim
1503
1504@sa Row, Column
1505*/
1506void SetTabSize( int _tabsize ){ tabsize = _tabsize; }
1507
1508int TabSize() const{ return tabsize; }
1509
1510/** If you have handled the error, it can be reset with this call. The error
1511state is automatically cleared if you Parse a new XML block.
1512*/
1513void ClearError(){error = false;
1514errorId = 0;
1515errorDesc = "";
1516errorLocation.row = errorLocation.col = 0;
1517//errorLocation.last = 0;
1518}
1519
1520/** Write the document to standard out using formatted printing ("pretty print"). */
1521void Print() const{ Print( stdout, 0 ); }
1522
1523/* Write the document to a string using formatted printing ("pretty print"). This
1524will allocate a character array (new char[]) and return it as a pointer. The
1525calling code pust call delete[] on the return char* to avoid a memory leak.
1526*/
1527//char* PrintToMemory() const;
1528
1529/// Print this Document to a FILE stream.
1530virtual void Print( FILE* cfile, int depth = 0 ) const;
1531// [internal use]
1532void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding );
1533
1534virtual const TiXmlDocument* ToDocument() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1535virtual TiXmlDocument* ToDocument() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1536
1537/** Walk the XML tree visiting this node and all of its children.
1538*/
1539virtual bool Accept( TiXmlVisitor* content ) const;
1540
1541protected :
1542// [internal use]
1543virtual TiXmlNode* Clone() const;
1544#ifdef TIXML_USE_STL
1545virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
1546#endif
1547
1548private:
1549void CopyTo( TiXmlDocument* target ) const;
1550
1551bool error;
1552int errorId;
1553TIXML_STRING errorDesc;
1554int tabsize;
1555TiXmlCursor errorLocation;
1556bool useMicrosoftBOM;// the UTF-8 BOM were found when read. Note this, and try to write.
1557};
1558
1559
1560/**
1561A TiXmlHandle is a class that wraps a node pointer with null checks; this is
1562an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml
1563DOM structure. It is a separate utility class.
1564
1565Take an example:
1566@verbatim
1567<Document>
1568<Element attributeA = "valueA">
1569<Child attributeB = "value1" />
1570<Child attributeB = "value2" />
1571</Element>
1572<Document>
1573@endverbatim
1574
1575Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very
1576easy to write a *lot* of code that looks like:
1577
1578@verbatim
1579TiXmlElement* root = document.FirstChildElement( "Document" );
1580if ( root )
1581{
1582TiXmlElement* element = root->FirstChildElement( "Element" );
1583if ( element )
1584{
1585TiXmlElement* child = element->FirstChildElement( "Child" );
1586if ( child )
1587{
1588TiXmlElement* child2 = child->NextSiblingElement( "Child" );
1589if ( child2 )
1590{
1591// Finally do something useful.
1592@endverbatim
1593
1594And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity
1595of such code. A TiXmlHandle checks for nullpointers so it is perfectly safe
1596and correct to use:
1597
1598@verbatim
1599TiXmlHandle docHandle( &document );
1600TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement();
1601if ( child2 )
1602{
1603// do something useful
1604@endverbatim
1605
1606Which is MUCH more concise and useful.
1607
1608It is also safe to copy handles - internally they are nothing more than node pointers.
1609@verbatim
1610TiXmlHandle handleCopy = handle;
1611@endverbatim
1612
1613What they should not be used for is iteration:
1614
1615@verbatim
1616int i=0;
1617while ( true )
1618{
1619TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement();
1620if ( !child )
1621break;
1622// do something
1623++i;
1624}
1625@endverbatim
1626
1627It seems reasonable, but it is in fact two embedded while loops. The Child method is
1628a linear walk to find the element, so this code would iterate much more than it needs
1629to. Instead, prefer:
1630
1631@verbatim
1632TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement();
1633
1634for( child; child; child=child->NextSiblingElement() )
1635{
1636// do something
1637}
1638@endverbatim
1639*/
1640class TiXmlHandle
1641{
1642public:
1643/// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
1644TiXmlHandle( TiXmlNode* _node ){ this->node = _node; }
1645/// Copy constructor
1646TiXmlHandle( const TiXmlHandle& ref ){ this->node = ref.node; }
1647TiXmlHandle operator=( const TiXmlHandle& ref ) { if ( &ref != this ) this->node = ref.node; return *this; }
1648
1649/// Return a handle to the first child node.
1650TiXmlHandle FirstChild() const;
1651/// Return a handle to the first child node with the given name.
1652TiXmlHandle FirstChild( const char * value ) const;
1653/// Return a handle to the first child element.
1654TiXmlHandle FirstChildElement() const;
1655/// Return a handle to the first child element with the given name.
1656TiXmlHandle FirstChildElement( const char * value ) const;
1657
1658/** Return a handle to the "index" child with the given name.
1659The first child is 0, the second 1, etc.
1660*/
1661TiXmlHandle Child( const char* value, int index ) const;
1662/** Return a handle to the "index" child.
1663The first child is 0, the second 1, etc.
1664*/
1665TiXmlHandle Child( int index ) const;
1666/** Return a handle to the "index" child element with the given name.
1667The first child element is 0, the second 1, etc. Note that only TiXmlElements
1668are indexed: other types are not counted.
1669*/
1670TiXmlHandle ChildElement( const char* value, int index ) const;
1671/** Return a handle to the "index" child element.
1672The first child element is 0, the second 1, etc. Note that only TiXmlElements
1673are indexed: other types are not counted.
1674*/
1675TiXmlHandle ChildElement( int index ) const;
1676
1677#ifdef TIXML_USE_STL
1678TiXmlHandle FirstChild( const std::string& _value ) const{ return FirstChild( _value.c_str() ); }
1679TiXmlHandle FirstChildElement( const std::string& _value ) const{ return FirstChildElement( _value.c_str() ); }
1680
1681TiXmlHandle Child( const std::string& _value, int index ) const{ return Child( _value.c_str(), index ); }
1682TiXmlHandle ChildElement( const std::string& _value, int index ) const{ return ChildElement( _value.c_str(), index ); }
1683#endif
1684
1685/** Return the handle as a TiXmlNode. This may return null.
1686*/
1687TiXmlNode* ToNode() const{ return node; }
1688/** Return the handle as a TiXmlElement. This may return null.
1689*/
1690TiXmlElement* ToElement() const{ return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
1691/**Return the handle as a TiXmlText. This may return null.
1692*/
1693TiXmlText* ToText() const{ return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
1694/** Return the handle as a TiXmlUnknown. This may return null.
1695*/
1696TiXmlUnknown* ToUnknown() const{ return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
1697
1698/** @deprecated use ToNode.
1699Return the handle as a TiXmlNode. This may return null.
1700*/
1701TiXmlNode* Node() const{ return ToNode(); }
1702/** @deprecated use ToElement.
1703Return the handle as a TiXmlElement. This may return null.
1704*/
1705TiXmlElement* Element() const{ return ToElement(); }
1706/**@deprecated use ToText()
1707Return the handle as a TiXmlText. This may return null.
1708*/
1709TiXmlText* Text() const{ return ToText(); }
1710/** @deprecated use ToUnknown()
1711Return the handle as a TiXmlUnknown. This may return null.
1712*/
1713TiXmlUnknown* Unknown() const{ return ToUnknown(); }
1714
1715private:
1716TiXmlNode* node;
1717};
1718
1719
1720/** Print to memory functionality. The TiXmlPrinter is useful when you need to:
1721
1722-# Print to memory (especially in non-STL mode)
1723-# Control formatting (line endings, etc.)
1724
1725When constructed, the TiXmlPrinter is in its default "pretty printing" mode.
1726Before calling Accept() you can call methods to control the printing
1727of the XML document. After TiXmlNode::Accept() is called, the printed document can
1728be accessed via the CStr(), Str(), and Size() methods.
1729
1730TiXmlPrinter uses the Visitor API.
1731@verbatim
1732TiXmlPrinter printer;
1733printer.SetIndent( "\t" );
1734
1735doc.Accept( &printer );
1736fprintf( stdout, "%s", printer.CStr() );
1737@endverbatim
1738*/
1739class TiXmlPrinter : public TiXmlVisitor
1740{
1741public:
1742TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ),
1743 buffer(), indent( " " ), lineBreak( "\n" ) {}
1744
1745virtual bool VisitEnter( const TiXmlDocument& doc );
1746virtual bool VisitExit( const TiXmlDocument& doc );
1747
1748virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute );
1749virtual bool VisitExit( const TiXmlElement& element );
1750
1751virtual bool Visit( const TiXmlDeclaration& declaration );
1752virtual bool Visit( const TiXmlText& text );
1753virtual bool Visit( const TiXmlComment& comment );
1754virtual bool Visit( const TiXmlUnknown& unknown );
1755
1756/** Set the indent characters for printing. By default 4 spaces
1757but tab (\t) is also useful, or null/empty string for no indentation.
1758*/
1759void SetIndent( const char* _indent ){ indent = _indent ? _indent : "" ; }
1760/// Query the indention string.
1761const char* Indent(){ return indent.c_str(); }
1762/** Set the line breaking string. By default set to newline (\n).
1763Some operating systems prefer other characters, or can be
1764set to the null/empty string for no indenation.
1765*/
1766void SetLineBreak( const char* _lineBreak ){ lineBreak = _lineBreak ? _lineBreak : ""; }
1767/// Query the current line breaking string.
1768const char* LineBreak(){ return lineBreak.c_str(); }
1769
1770/** Switch over to "stream printing" which is the most dense formatting without
1771linebreaks. Common when the XML is needed for network transmission.
1772*/
1773void SetStreamPrinting(){ indent = "";
1774 lineBreak = "";
1775}
1776/// Return the result.
1777const char* CStr(){ return buffer.c_str(); }
1778/// Return the length of the result string.
1779size_t Size(){ return buffer.size(); }
1780
1781#ifdef TIXML_USE_STL
1782/// Return the result.
1783const std::string& Str(){ return buffer; }
1784#endif
1785
1786private:
1787void DoIndent(){
1788for( int i=0; i<depth; ++i )
1789buffer += indent;
1790}
1791void DoLineBreak() {
1792buffer += lineBreak;
1793}
1794
1795int depth;
1796bool simpleTextPrint;
1797TIXML_STRING buffer;
1798TIXML_STRING indent;
1799TIXML_STRING lineBreak;
1800};
1801
1802
1803#ifdef _MSC_VER
1804#pragma warning( pop )
1805#endif
1806
1807#endif
1808

Archive Download this file

Revision: 1314