ZenLib
tinyxml.h
Go to the documentation of this file.
00001 /*
00002 www.sourceforge.net/projects/tinyxml
00003 Original code by Lee Thomason (www.grinninglizard.com)
00004 
00005 This software is provided 'as-is', without any express or implied
00006 warranty. In no event will the authors be held liable for any
00007 damages arising from the use of this software.
00008 
00009 Permission is granted to anyone to use this software for any
00010 purpose, including commercial applications, and to alter it and
00011 redistribute it freely, subject to the following restrictions:
00012 
00013 1. The origin of this software must not be misrepresented; you must
00014 not claim that you wrote the original software. If you use this
00015 software in a product, an acknowledgment in the product documentation
00016 would be appreciated but is not required.
00017 
00018 2. Altered source versions must be plainly marked as such, and
00019 must not be misrepresented as being the original software.
00020 
00021 3. This notice may not be removed or altered from any source
00022 distribution.
00023 */
00024 
00025 
00026 #ifndef TINYXML_INCLUDED
00027 #define TINYXML_INCLUDED
00028 
00029 #ifdef _MSC_VER
00030 #pragma warning( push )
00031 #pragma warning( disable : 4530 )
00032 #pragma warning( disable : 4786 )
00033 #endif
00034 
00035 #include <ctype.h>
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039 #include <assert.h>
00040 
00041 // Help out windows:
00042 #if defined( _DEBUG ) && !defined( DEBUG )
00043 #define DEBUG
00044 #endif
00045 
00046 #define TIXML_USE_STL
00047 #ifdef TIXML_USE_STL
00048         #include <string>
00049         #include <iostream>
00050         #include <sstream>
00051         #define TIXML_STRING            std::string
00052 #else
00053         #include "tinystr.h"
00054         #define TIXML_STRING            TiXmlString
00055 #endif
00056 
00057 // Deprecated library function hell. Compilers want to use the
00058 // new safe versions. This probably doesn't fully address the problem,
00059 // but it gets closer. There are too many compilers for me to fully
00060 // test. If you get compilation troubles, undefine TIXML_SAFE
00061 #define TIXML_SAFE
00062 
00063 #ifdef TIXML_SAFE
00064         #if defined(_MSC_VER) && (_MSC_VER >= 1400 )
00065                 // Microsoft visual studio, version 2005 and higher.
00066                 #define TIXML_SNPRINTF _snprintf_s
00067                 #define TIXML_SSCANF   sscanf_s
00068         #elif defined(_MSC_VER) && (_MSC_VER >= 1200 )
00069                 // Microsoft visual studio, version 6 and higher.
00070                 //#pragma message( "Using _sn* functions." )
00071                 #define TIXML_SNPRINTF _snprintf
00072                 #define TIXML_SSCANF   sscanf
00073         #elif defined(__GNUC__) && (__GNUC__ >= 3 )
00074                 // GCC version 3 and higher.s
00075                 //#warning( "Using sn* functions." )
00076                 #define TIXML_SNPRINTF snprintf
00077                 #define TIXML_SSCANF   sscanf
00078         #else
00079                 #define TIXML_SNPRINTF snprintf
00080                 #define TIXML_SSCANF   sscanf
00081         #endif
00082 #endif  
00083 
00084 class TiXmlDocument;
00085 class TiXmlElement;
00086 class TiXmlComment;
00087 class TiXmlUnknown;
00088 class TiXmlAttribute;
00089 class TiXmlText;
00090 class TiXmlDeclaration;
00091 class TiXmlParsingData;
00092 
00093 const int TIXML_MAJOR_VERSION = 2;
00094 const int TIXML_MINOR_VERSION = 6;
00095 const int TIXML_PATCH_VERSION = 2;
00096 
00097 /*      Internal structure for tracking location of items 
00098         in the XML file.
00099 */
00100 struct TiXmlCursor
00101 {
00102         TiXmlCursor()           { Clear(); }
00103         void Clear()            { row = col = -1; }
00104 
00105         int row;        // 0 based.
00106         int col;        // 0 based.
00107 };
00108 
00109 
00110 /**
00111         Implements the interface to the "Visitor pattern" (see the Accept() method.)
00112         If you call the Accept() method, it requires being passed a TiXmlVisitor
00113         class to handle callbacks. For nodes that contain other nodes (Document, Element)
00114         you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves
00115         are simply called with Visit().
00116 
00117         If you return 'true' from a Visit method, recursive parsing will continue. If you return
00118         false, <b>no children of this node or its sibilings</b> will be Visited.
00119 
00120         All flavors of Visit methods have a default implementation that returns 'true' (continue 
00121         visiting). You need to only override methods that are interesting to you.
00122 
00123         Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting.
00124 
00125         You should never change the document from a callback.
00126 
00127         @sa TiXmlNode::Accept()
00128 */
00129 class TiXmlVisitor
00130 {
00131 public:
00132         virtual ~TiXmlVisitor() {}
00133 
00134         /// Visit a document.
00135         virtual bool VisitEnter( const TiXmlDocument& /*doc*/ )                 { return true; }
00136         /// Visit a document.
00137         virtual bool VisitExit( const TiXmlDocument& /*doc*/ )                  { return true; }
00138 
00139         /// Visit an element.
00140         virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ )    { return true; }
00141         /// Visit an element.
00142         virtual bool VisitExit( const TiXmlElement& /*element*/ )               { return true; }
00143 
00144         /// Visit a declaration
00145         virtual bool Visit( const TiXmlDeclaration& /*declaration*/ )   { return true; }
00146         /// Visit a text node
00147         virtual bool Visit( const TiXmlText& /*text*/ )                                 { return true; }
00148         /// Visit a comment node
00149         virtual bool Visit( const TiXmlComment& /*comment*/ )                   { return true; }
00150         /// Visit an unknown node
00151         virtual bool Visit( const TiXmlUnknown& /*unknown*/ )                   { return true; }
00152 };
00153 
00154 // Only used by Attribute::Query functions
00155 enum 
00156 { 
00157         TIXML_SUCCESS,
00158         TIXML_NO_ATTRIBUTE,
00159         TIXML_WRONG_TYPE
00160 };
00161 
00162 
00163 // Used by the parsing routines.
00164 enum TiXmlEncoding
00165 {
00166         TIXML_ENCODING_UNKNOWN,
00167         TIXML_ENCODING_UTF8,
00168         TIXML_ENCODING_LEGACY
00169 };
00170 
00171 const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN;
00172 
00173 /** TiXmlBase is a base class for every class in TinyXml.
00174         It does little except to establish that TinyXml classes
00175         can be printed and provide some utility functions.
00176 
00177         In XML, the document and elements can contain
00178         other elements and other types of nodes.
00179 
00180         @verbatim
00181         A Document can contain: Element (container or leaf)
00182                                                         Comment (leaf)
00183                                                         Unknown (leaf)
00184                                                         Declaration( leaf )
00185 
00186         An Element can contain: Element (container or leaf)
00187                                                         Text    (leaf)
00188                                                         Attributes (not on tree)
00189                                                         Comment (leaf)
00190                                                         Unknown (leaf)
00191 
00192         A Decleration contains: Attributes (not on tree)
00193         @endverbatim
00194 */
00195 class TiXmlBase
00196 {
00197         friend class TiXmlNode;
00198         friend class TiXmlElement;
00199         friend class TiXmlDocument;
00200 
00201 public:
00202         TiXmlBase()     :       userData(0)             {}
00203         virtual ~TiXmlBase()                    {}
00204 
00205         /**     All TinyXml classes can print themselves to a filestream
00206                 or the string class (TiXmlString in non-STL mode, std::string
00207                 in STL mode.) Either or both cfile and str can be null.
00208                 
00209                 This is a formatted print, and will insert 
00210                 tabs and newlines.
00211                 
00212                 (For an unformatted stream, use the << operator.)
00213         */
00214         virtual void Print( FILE* cfile, int depth ) const = 0;
00215 
00216         /**     The world does not agree on whether white space should be kept or
00217                 not. In order to make everyone happy, these global, static functions
00218                 are provided to set whether or not TinyXml will condense all white space
00219                 into a single space or not. The default is to condense. Note changing this
00220                 value is not thread safe.
00221         */
00222         static void SetCondenseWhiteSpace( bool condense )              { condenseWhiteSpace = condense; }
00223 
00224         /// Return the current white space setting.
00225         static bool IsWhiteSpaceCondensed()                                             { return condenseWhiteSpace; }
00226 
00227         /** Return the position, in the original source file, of this node or attribute.
00228                 The row and column are 1-based. (That is the first row and first column is
00229                 1,1). If the returns values are 0 or less, then the parser does not have
00230                 a row and column value.
00231 
00232                 Generally, the row and column value will be set when the TiXmlDocument::Load(),
00233                 TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set
00234                 when the DOM was created from operator>>.
00235 
00236                 The values reflect the initial load. Once the DOM is modified programmatically
00237                 (by adding or changing nodes and attributes) the new values will NOT update to
00238                 reflect changes in the document.
00239 
00240                 There is a minor performance cost to computing the row and column. Computation
00241                 can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value.
00242 
00243                 @sa TiXmlDocument::SetTabSize()
00244         */
00245         int Row() const                 { return location.row + 1; }
00246         int Column() const              { return location.col + 1; }    ///< See Row()
00247 
00248         void  SetUserData( void* user )                 { userData = user; }    ///< Set a pointer to arbitrary user data.
00249         void* GetUserData()                                             { return userData; }    ///< Get a pointer to arbitrary user data.
00250         const void* GetUserData() const                 { return userData; }    ///< Get a pointer to arbitrary user data.
00251 
00252         // Table that returs, for a given lead byte, the total number of bytes
00253         // in the UTF-8 sequence.
00254         static const int utf8ByteTable[256];
00255 
00256         virtual const char* Parse(      const char* p, 
00257                                                                 TiXmlParsingData* data, 
00258                                                                 TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0;
00259 
00260         /** Expands entities in a string. Note this should not contian the tag's '<', '>', etc, 
00261                 or they will be transformed into entities!
00262         */
00263         static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out );
00264 
00265         enum
00266         {
00267                 TIXML_NO_ERROR = 0,
00268                 TIXML_ERROR,
00269                 TIXML_ERROR_OPENING_FILE,
00270                 TIXML_ERROR_PARSING_ELEMENT,
00271                 TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
00272                 TIXML_ERROR_READING_ELEMENT_VALUE,
00273                 TIXML_ERROR_READING_ATTRIBUTES,
00274                 TIXML_ERROR_PARSING_EMPTY,
00275                 TIXML_ERROR_READING_END_TAG,
00276                 TIXML_ERROR_PARSING_UNKNOWN,
00277                 TIXML_ERROR_PARSING_COMMENT,
00278                 TIXML_ERROR_PARSING_DECLARATION,
00279                 TIXML_ERROR_DOCUMENT_EMPTY,
00280                 TIXML_ERROR_EMBEDDED_NULL,
00281                 TIXML_ERROR_PARSING_CDATA,
00282                 TIXML_ERROR_DOCUMENT_TOP_ONLY,
00283 
00284                 TIXML_ERROR_STRING_COUNT
00285         };
00286 
00287 protected:
00288 
00289         static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding );
00290 
00291         inline static bool IsWhiteSpace( char c )               
00292         { 
00293                 return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); 
00294         }
00295         inline static bool IsWhiteSpace( int c )
00296         {
00297                 if ( c < 256 )
00298                         return IsWhiteSpace( (char) c );
00299                 return false;   // Again, only truly correct for English/Latin...but usually works.
00300         }
00301 
00302         #ifdef TIXML_USE_STL
00303         static bool     StreamWhiteSpace( std::istream * in, TIXML_STRING * tag );
00304         static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag );
00305         #endif
00306 
00307         /*      Reads an XML name into the string provided. Returns
00308                 a pointer just past the last character of the name,
00309                 or 0 if the function has an error.
00310         */
00311         static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding );
00312 
00313         /*      Reads text. Returns a pointer past the given end tag.
00314                 Wickedly complex options, but it keeps the (sensitive) code in one place.
00315         */
00316         static const char* ReadText(    const char* in,                         // where to start
00317                                                                         TIXML_STRING* text,                     // the string read
00318                                                                         bool ignoreWhiteSpace,          // whether to keep the white space
00319                                                                         const char* endTag,                     // what ends this text
00320                                                                         bool ignoreCase,                        // whether to ignore case in the end tag
00321                                                                         TiXmlEncoding encoding );       // the current encoding
00322 
00323         // If an entity has been found, transform it into a character.
00324         static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding );
00325 
00326         // Get a character, while interpreting entities.
00327         // The length can be from 0 to 4 bytes.
00328         inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding )
00329         {
00330                 assert( p );
00331                 if ( encoding == TIXML_ENCODING_UTF8 )
00332                 {
00333                         *length = utf8ByteTable[ *((const unsigned char*)p) ];
00334                         assert( *length >= 0 && *length < 5 );
00335                 }
00336                 else
00337                 {
00338                         *length = 1;
00339                 }
00340 
00341                 if ( *length == 1 )
00342                 {
00343                         if ( *p == '&' )
00344                                 return GetEntity( p, _value, length, encoding );
00345                         *_value = *p;
00346                         return p+1;
00347                 }
00348                 else if ( *length )
00349                 {
00350                         //strncpy( _value, p, *length );        // lots of compilers don't like this function (unsafe),
00351                                                                                                 // and the null terminator isn't needed
00352                         for( int i=0; p[i] && i<*length; ++i ) {
00353                                 _value[i] = p[i];
00354                         }
00355                         return p + (*length);
00356                 }
00357                 else
00358                 {
00359                         // Not valid text.
00360                         return 0;
00361                 }
00362         }
00363 
00364         // Return true if the next characters in the stream are any of the endTag sequences.
00365         // Ignore case only works for english, and should only be relied on when comparing
00366         // to English words: StringEqual( p, "version", true ) is fine.
00367         static bool StringEqual(        const char* p,
00368                                                                 const char* endTag,
00369                                                                 bool ignoreCase,
00370                                                                 TiXmlEncoding encoding );
00371 
00372         static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
00373 
00374         TiXmlCursor location;
00375 
00376     /// Field containing a generic user pointer
00377         void*                   userData;
00378         
00379         // None of these methods are reliable for any language except English.
00380         // Good for approximation, not great for accuracy.
00381         static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding );
00382         static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding );
00383         inline static int ToLower( int v, TiXmlEncoding encoding )
00384         {
00385                 if ( encoding == TIXML_ENCODING_UTF8 )
00386                 {
00387                         if ( v < 128 ) return tolower( v );
00388                         return v;
00389                 }
00390                 else
00391                 {
00392                         return tolower( v );
00393                 }
00394         }
00395         static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
00396 
00397 private:
00398         TiXmlBase( const TiXmlBase& );                          // not implemented.
00399         void operator=( const TiXmlBase& base );        // not allowed.
00400 
00401         struct Entity
00402         {
00403                 const char*     str;
00404                 unsigned int    strLength;
00405                 char                chr;
00406         };
00407         enum
00408         {
00409                 NUM_ENTITY = 5,
00410                 MAX_ENTITY_LENGTH = 6
00411 
00412         };
00413         static Entity entity[ NUM_ENTITY ];
00414         static bool condenseWhiteSpace;
00415 };
00416 
00417 
00418 /** The parent class for everything in the Document Object Model.
00419         (Except for attributes).
00420         Nodes have siblings, a parent, and children. A node can be
00421         in a document, or stand on its own. The type of a TiXmlNode
00422         can be queried, and it can be cast to its more defined type.
00423 */
00424 class TiXmlNode : public TiXmlBase
00425 {
00426         friend class TiXmlDocument;
00427         friend class TiXmlElement;
00428 
00429 public:
00430         #ifdef TIXML_USE_STL    
00431 
00432             /** An input stream operator, for every class. Tolerant of newlines and
00433                     formatting, but doesn't expect them.
00434             */
00435             friend std::istream& operator >> (std::istream& in, TiXmlNode& base);
00436 
00437             /** An output stream operator, for every class. Note that this outputs
00438                     without any newlines or formatting, as opposed to Print(), which
00439                     includes tabs and new lines.
00440 
00441                     The operator<< and operator>> are not completely symmetric. Writing
00442                     a node to a stream is very well defined. You'll get a nice stream
00443                     of output, without any extra whitespace or newlines.
00444                     
00445                     But reading is not as well defined. (As it always is.) If you create
00446                     a TiXmlElement (for example) and read that from an input stream,
00447                     the text needs to define an element or junk will result. This is
00448                     true of all input streams, but it's worth keeping in mind.
00449 
00450                     A TiXmlDocument will read nodes until it reads a root element, and
00451                         all the children of that root element.
00452             */  
00453             friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base);
00454 
00455                 /// Appends the XML node or attribute to a std::string.
00456                 friend std::string& operator<< (std::string& out, const TiXmlNode& base );
00457 
00458         #endif
00459 
00460         /** The types of XML nodes supported by TinyXml. (All the
00461                         unsupported types are picked up by UNKNOWN.)
00462         */
00463         enum NodeType
00464         {
00465                 TINYXML_DOCUMENT,
00466                 TINYXML_ELEMENT,
00467                 TINYXML_COMMENT,
00468                 TINYXML_UNKNOWN,
00469                 TINYXML_TEXT,
00470                 TINYXML_DECLARATION,
00471                 TINYXML_TYPECOUNT
00472         };
00473 
00474         virtual ~TiXmlNode();
00475 
00476         /** The meaning of 'value' changes for the specific type of
00477                 TiXmlNode.
00478                 @verbatim
00479                 Document:       filename of the xml file
00480                 Element:        name of the element
00481                 Comment:        the comment text
00482                 Unknown:        the tag contents
00483                 Text:           the text string
00484                 @endverbatim
00485 
00486                 The subclasses will wrap this function.
00487         */
00488         const char *Value() const { return value.c_str (); }
00489 
00490     #ifdef TIXML_USE_STL
00491         /** Return Value() as a std::string. If you only use STL,
00492             this is more efficient than calling Value().
00493                 Only available in STL mode.
00494         */
00495         const std::string& ValueStr() const { return value; }
00496         #endif
00497 
00498         const TIXML_STRING& ValueTStr() const { return value; }
00499 
00500         /** Changes the value of the node. Defined as:
00501                 @verbatim
00502                 Document:       filename of the xml file
00503                 Element:        name of the element
00504                 Comment:        the comment text
00505                 Unknown:        the tag contents
00506                 Text:           the text string
00507                 @endverbatim
00508         */
00509         void SetValue(const char * _value) { value = _value;}
00510 
00511     #ifdef TIXML_USE_STL
00512         /// STL std::string form.
00513         void SetValue( const std::string& _value )      { value = _value; }
00514         #endif
00515 
00516         /// Delete all the children of this node. Does not affect 'this'.
00517         void Clear();
00518 
00519         /// One step up the DOM.
00520         TiXmlNode* Parent()                                                     { return parent; }
00521         const TiXmlNode* Parent() const                         { return parent; }
00522 
00523         const TiXmlNode* FirstChild()   const           { return firstChild; }  ///< The first child of this node. Will be null if there are no children.
00524         TiXmlNode* FirstChild()                                         { return firstChild; }
00525         const TiXmlNode* FirstChild( const char * value ) const;                        ///< The first child of this node with the matching 'value'. Will be null if none found.
00526         /// The first child of this node with the matching 'value'. Will be null if none found.
00527         TiXmlNode* FirstChild( const char * _value ) {
00528                 // Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe)
00529                 // call the method, cast the return back to non-const.
00530                 return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value ));
00531         }
00532         const TiXmlNode* LastChild() const      { return lastChild; }           /// The last child of this node. Will be null if there are no children.
00533         TiXmlNode* LastChild()  { return lastChild; }
00534         
00535         const TiXmlNode* LastChild( const char * value ) const;                 /// The last child of this node matching 'value'. Will be null if there are no children.
00536         TiXmlNode* LastChild( const char * _value ) {
00537                 return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value ));
00538         }
00539 
00540     #ifdef TIXML_USE_STL
00541         const TiXmlNode* FirstChild( const std::string& _value ) const  {       return FirstChild (_value.c_str ());    }       ///< STL std::string form.
00542         TiXmlNode* FirstChild( const std::string& _value )                              {       return FirstChild (_value.c_str ());    }       ///< STL std::string form.
00543         const TiXmlNode* LastChild( const std::string& _value ) const   {       return LastChild (_value.c_str ());     }       ///< STL std::string form.
00544         TiXmlNode* LastChild( const std::string& _value )                               {       return LastChild (_value.c_str ());     }       ///< STL std::string form.
00545         #endif
00546 
00547         /** An alternate way to walk the children of a node.
00548                 One way to iterate over nodes is:
00549                 @verbatim
00550                         for( child = parent->FirstChild(); child; child = child->NextSibling() )
00551                 @endverbatim
00552 
00553                 IterateChildren does the same thing with the syntax:
00554                 @verbatim
00555                         child = 0;
00556                         while( child = parent->IterateChildren( child ) )
00557                 @endverbatim
00558 
00559                 IterateChildren takes the previous child as input and finds
00560                 the next one. If the previous child is null, it returns the
00561                 first. IterateChildren will return null when done.
00562         */
00563         const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const;
00564         TiXmlNode* IterateChildren( const TiXmlNode* previous ) {
00565                 return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) );
00566         }
00567 
00568         /// This flavor of IterateChildren searches for children with a particular 'value'
00569         const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const;
00570         TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) {
00571                 return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) );
00572         }
00573 
00574     #ifdef TIXML_USE_STL
00575         const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const  {       return IterateChildren (_value.c_str (), previous);     }       ///< STL std::string form.
00576         TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) {    return IterateChildren (_value.c_str (), previous);     }       ///< STL std::string form.
00577         #endif
00578 
00579         /** Add a new node related to this. Adds a child past the LastChild.
00580                 Returns a pointer to the new object or NULL if an error occured.
00581         */
00582         TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
00583 
00584 
00585         /** Add a new node related to this. Adds a child past the LastChild.
00586 
00587                 NOTE: the node to be added is passed by pointer, and will be
00588                 henceforth owned (and deleted) by tinyXml. This method is efficient
00589                 and avoids an extra copy, but should be used with care as it
00590                 uses a different memory model than the other insert functions.
00591 
00592                 @sa InsertEndChild
00593         */
00594         TiXmlNode* LinkEndChild( TiXmlNode* addThis );
00595 
00596         /** Add a new node related to this. Adds a child before the specified child.
00597                 Returns a pointer to the new object or NULL if an error occured.
00598         */
00599         TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
00600 
00601         /** Add a new node related to this. Adds a child after the specified child.
00602                 Returns a pointer to the new object or NULL if an error occured.
00603         */
00604         TiXmlNode* InsertAfterChild(  TiXmlNode* afterThis, const TiXmlNode& addThis );
00605 
00606         /** Replace a child of this node.
00607                 Returns a pointer to the new object or NULL if an error occured.
00608         */
00609         TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
00610 
00611         /// Delete a child of this node.
00612         bool RemoveChild( TiXmlNode* removeThis );
00613 
00614         /// Navigate to a sibling node.
00615         const TiXmlNode* PreviousSibling() const                        { return prev; }
00616         TiXmlNode* PreviousSibling()                                            { return prev; }
00617 
00618         /// Navigate to a sibling node.
00619         const TiXmlNode* PreviousSibling( const char * ) const;
00620         TiXmlNode* PreviousSibling( const char *_prev ) {
00621                 return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) );
00622         }
00623 
00624     #ifdef TIXML_USE_STL
00625         const TiXmlNode* PreviousSibling( const std::string& _value ) const     {       return PreviousSibling (_value.c_str ());       }       ///< STL std::string form.
00626         TiXmlNode* PreviousSibling( const std::string& _value )                         {       return PreviousSibling (_value.c_str ());       }       ///< STL std::string form.
00627         const TiXmlNode* NextSibling( const std::string& _value) const          {       return NextSibling (_value.c_str ());   }       ///< STL std::string form.
00628         TiXmlNode* NextSibling( const std::string& _value)                                      {       return NextSibling (_value.c_str ());   }       ///< STL std::string form.
00629         #endif
00630 
00631         /// Navigate to a sibling node.
00632         const TiXmlNode* NextSibling() const                            { return next; }
00633         TiXmlNode* NextSibling()                                                        { return next; }
00634 
00635         /// Navigate to a sibling node with the given 'value'.
00636         const TiXmlNode* NextSibling( const char * ) const;
00637         TiXmlNode* NextSibling( const char* _next ) {
00638                 return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) );
00639         }
00640 
00641         /** Convenience function to get through elements.
00642                 Calls NextSibling and ToElement. Will skip all non-Element
00643                 nodes. Returns 0 if there is not another element.
00644         */
00645         const TiXmlElement* NextSiblingElement() const;
00646         TiXmlElement* NextSiblingElement() {
00647                 return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() );
00648         }
00649 
00650         /** Convenience function to get through elements.
00651                 Calls NextSibling and ToElement. Will skip all non-Element
00652                 nodes. Returns 0 if there is not another element.
00653         */
00654         const TiXmlElement* NextSiblingElement( const char * ) const;
00655         TiXmlElement* NextSiblingElement( const char *_next ) {
00656                 return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) );
00657         }
00658 
00659     #ifdef TIXML_USE_STL
00660         const TiXmlElement* NextSiblingElement( const std::string& _value) const        {       return NextSiblingElement (_value.c_str ());    }       ///< STL std::string form.
00661         TiXmlElement* NextSiblingElement( const std::string& _value)                            {       return NextSiblingElement (_value.c_str ());    }       ///< STL std::string form.
00662         #endif
00663 
00664         /// Convenience function to get through elements.
00665         const TiXmlElement* FirstChildElement() const;
00666         TiXmlElement* FirstChildElement() {
00667                 return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() );
00668         }
00669 
00670         /// Convenience function to get through elements.
00671         const TiXmlElement* FirstChildElement( const char * _value ) const;
00672         TiXmlElement* FirstChildElement( const char * _value ) {
00673                 return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) );
00674         }
00675 
00676     #ifdef TIXML_USE_STL
00677         const TiXmlElement* FirstChildElement( const std::string& _value ) const        {       return FirstChildElement (_value.c_str ());     }       ///< STL std::string form.
00678         TiXmlElement* FirstChildElement( const std::string& _value )                            {       return FirstChildElement (_value.c_str ());     }       ///< STL std::string form.
00679         #endif
00680 
00681         /** Query the type (as an enumerated value, above) of this node.
00682                 The possible types are: TINYXML_DOCUMENT, TINYXML_ELEMENT, TINYXML_COMMENT,
00683                                                                 TINYXML_UNKNOWN, TINYXML_TEXT, and TINYXML_DECLARATION.
00684         */
00685         int Type() const        { return type; }
00686 
00687         /** Return a pointer to the Document this node lives in.
00688                 Returns null if not in a document.
00689         */
00690         const TiXmlDocument* GetDocument() const;
00691         TiXmlDocument* GetDocument() {
00692                 return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() );
00693         }
00694 
00695         /// Returns true if this node has no children.
00696         bool NoChildren() const                                         { return !firstChild; }
00697 
00698         virtual const TiXmlDocument*    ToDocument()    const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
00699         virtual const TiXmlElement*     ToElement()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
00700         virtual const TiXmlComment*     ToComment()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
00701         virtual const TiXmlUnknown*     ToUnknown()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
00702         virtual const TiXmlText*        ToText()        const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
00703         virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
00704 
00705         virtual TiXmlDocument*          ToDocument()    { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
00706         virtual TiXmlElement*           ToElement()         { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
00707         virtual TiXmlComment*           ToComment()     { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
00708         virtual TiXmlUnknown*           ToUnknown()         { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
00709         virtual TiXmlText*                  ToText()        { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
00710         virtual TiXmlDeclaration*       ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
00711 
00712         /** Create an exact duplicate of this node and return it. The memory must be deleted
00713                 by the caller. 
00714         */
00715         virtual TiXmlNode* Clone() const = 0;
00716 
00717         /** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the 
00718                 XML tree will be conditionally visited and the host will be called back
00719                 via the TiXmlVisitor interface.
00720 
00721                 This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse
00722                 the XML for the callbacks, so the performance of TinyXML is unchanged by using this
00723                 interface versus any other.)
00724 
00725                 The interface has been based on ideas from:
00726 
00727                 - http://www.saxproject.org/
00728                 - http://c2.com/cgi/wiki?HierarchicalVisitorPattern 
00729 
00730                 Which are both good references for "visiting".
00731 
00732                 An example of using Accept():
00733                 @verbatim
00734                 TiXmlPrinter printer;
00735                 tinyxmlDoc.Accept( &printer );
00736                 const char* xmlcstr = printer.CStr();
00737                 @endverbatim
00738         */
00739         virtual bool Accept( TiXmlVisitor* visitor ) const = 0;
00740 
00741 protected:
00742         TiXmlNode( NodeType _type );
00743 
00744         // Copy to the allocated object. Shared functionality between Clone, Copy constructor,
00745         // and the assignment operator.
00746         void CopyTo( TiXmlNode* target ) const;
00747 
00748         #ifdef TIXML_USE_STL
00749             // The real work of the input operator.
00750         virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0;
00751         #endif
00752 
00753         // Figure out what is at *p, and parse it. Returns null if it is not an xml node.
00754         TiXmlNode* Identify( const char* start, TiXmlEncoding encoding );
00755 
00756         TiXmlNode*              parent;
00757         NodeType                type;
00758 
00759         TiXmlNode*              firstChild;
00760         TiXmlNode*              lastChild;
00761 
00762         TIXML_STRING    value;
00763 
00764         TiXmlNode*              prev;
00765         TiXmlNode*              next;
00766 
00767 private:
00768         TiXmlNode( const TiXmlNode& );                          // not implemented.
00769         void operator=( const TiXmlNode& base );        // not allowed.
00770 };
00771 
00772 
00773 /** An attribute is a name-value pair. Elements have an arbitrary
00774         number of attributes, each with a unique name.
00775 
00776         @note The attributes are not TiXmlNodes, since they are not
00777                   part of the tinyXML document object model. There are other
00778                   suggested ways to look at this problem.
00779 */
00780 class TiXmlAttribute : public TiXmlBase
00781 {
00782         friend class TiXmlAttributeSet;
00783 
00784 public:
00785         /// Construct an empty attribute.
00786         TiXmlAttribute() : TiXmlBase()
00787         {
00788                 document = 0;
00789                 prev = next = 0;
00790         }
00791 
00792         #ifdef TIXML_USE_STL
00793         /// std::string constructor.
00794         TiXmlAttribute( const std::string& _name, const std::string& _value )
00795         {
00796                 name = _name;
00797                 value = _value;
00798                 document = 0;
00799                 prev = next = 0;
00800         }
00801         #endif
00802 
00803         /// Construct an attribute with a name and value.
00804         TiXmlAttribute( const char * _name, const char * _value )
00805         {
00806                 name = _name;
00807                 value = _value;
00808                 document = 0;
00809                 prev = next = 0;
00810         }
00811 
00812         const char*             Name()  const           { return name.c_str(); }                ///< Return the name of this attribute.
00813         const char*             Value() const           { return value.c_str(); }               ///< Return the value of this attribute.
00814         #ifdef TIXML_USE_STL
00815         const std::string& ValueStr() const     { return value; }                               ///< Return the value of this attribute.
00816         #endif
00817         int                             IntValue() const;                                                                       ///< Return the value of this attribute, converted to an integer.
00818         double                  DoubleValue() const;                                                            ///< Return the value of this attribute, converted to a double.
00819 
00820         // Get the tinyxml string representation
00821         const TIXML_STRING& NameTStr() const { return name; }
00822 
00823         /** QueryIntValue examines the value string. It is an alternative to the
00824                 IntValue() method with richer error checking.
00825                 If the value is an integer, it is stored in 'value' and 
00826                 the call returns TIXML_SUCCESS. If it is not
00827                 an integer, it returns TIXML_WRONG_TYPE.
00828 
00829                 A specialized but useful call. Note that for success it returns 0,
00830                 which is the opposite of almost all other TinyXml calls.
00831         */
00832         int QueryIntValue( int* _value ) const;
00833         /// QueryDoubleValue examines the value string. See QueryIntValue().
00834         int QueryDoubleValue( double* _value ) const;
00835 
00836         void SetName( const char* _name )       { name = _name; }                               ///< Set the name of this attribute.
00837         void SetValue( const char* _value )     { value = _value; }                             ///< Set the value.
00838 
00839         void SetIntValue( int _value );                                                                         ///< Set the value from an integer.
00840         void SetDoubleValue( double _value );                                                           ///< Set the value from a double.
00841 
00842     #ifdef TIXML_USE_STL
00843         /// STL std::string form.
00844         void SetName( const std::string& _name )        { name = _name; }       
00845         /// STL std::string form.       
00846         void SetValue( const std::string& _value )      { value = _value; }
00847         #endif
00848 
00849         /// Get the next sibling attribute in the DOM. Returns null at end.
00850         const TiXmlAttribute* Next() const;
00851         TiXmlAttribute* Next() {
00852                 return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() ); 
00853         }
00854 
00855         /// Get the previous sibling attribute in the DOM. Returns null at beginning.
00856         const TiXmlAttribute* Previous() const;
00857         TiXmlAttribute* Previous() {
00858                 return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() ); 
00859         }
00860 
00861         bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
00862         bool operator<( const TiXmlAttribute& rhs )      const { return name < rhs.name; }
00863         bool operator>( const TiXmlAttribute& rhs )  const { return name > rhs.name; }
00864 
00865         /*      Attribute parsing starts: first letter of the name
00866                                                  returns: the next char after the value end quote
00867         */
00868         virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
00869 
00870         // Prints this Attribute to a FILE stream.
00871         virtual void Print( FILE* cfile, int depth ) const {
00872                 Print( cfile, depth, 0 );
00873         }
00874         void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
00875 
00876         // [internal use]
00877         // Set the document pointer so the attribute can report errors.
00878         void SetDocument( TiXmlDocument* doc )  { document = doc; }
00879 
00880 private:
00881         TiXmlAttribute( const TiXmlAttribute& );                                // not implemented.
00882         void operator=( const TiXmlAttribute& base );   // not allowed.
00883 
00884         TiXmlDocument*  document;       // A pointer back to a document, for error reporting.
00885         TIXML_STRING name;
00886         TIXML_STRING value;
00887         TiXmlAttribute* prev;
00888         TiXmlAttribute* next;
00889 };
00890 
00891 
00892 /*      A class used to manage a group of attributes.
00893         It is only used internally, both by the ELEMENT and the DECLARATION.
00894         
00895         The set can be changed transparent to the Element and Declaration
00896         classes that use it, but NOT transparent to the Attribute
00897         which has to implement a next() and previous() method. Which makes
00898         it a bit problematic and prevents the use of STL.
00899 
00900         This version is implemented with circular lists because:
00901                 - I like circular lists
00902                 - it demonstrates some independence from the (typical) doubly linked list.
00903 */
00904 class TiXmlAttributeSet
00905 {
00906 public:
00907         TiXmlAttributeSet();
00908         ~TiXmlAttributeSet();
00909 
00910         void Add( TiXmlAttribute* attribute );
00911         void Remove( TiXmlAttribute* attribute );
00912 
00913         const TiXmlAttribute* First()   const   { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
00914         TiXmlAttribute* First()                                 { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
00915         const TiXmlAttribute* Last() const              { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
00916         TiXmlAttribute* Last()                                  { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
00917 
00918         TiXmlAttribute* Find( const char* _name ) const;
00919         TiXmlAttribute* FindOrCreate( const char* _name );
00920 
00921 #       ifdef TIXML_USE_STL
00922         TiXmlAttribute* Find( const std::string& _name ) const;
00923         TiXmlAttribute* FindOrCreate( const std::string& _name );
00924 #       endif
00925 
00926 
00927 private:
00928         //*ME:  Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element),
00929         //*ME:  this class must be also use a hidden/disabled copy-constructor !!!
00930         TiXmlAttributeSet( const TiXmlAttributeSet& );  // not allowed
00931         void operator=( const TiXmlAttributeSet& );     // not allowed (as TiXmlAttribute)
00932 
00933         TiXmlAttribute sentinel;
00934 };
00935 
00936 
00937 /** The element is a container class. It has a value, the element name,
00938         and can contain other elements, text, comments, and unknowns.
00939         Elements also contain an arbitrary number of attributes.
00940 */
00941 class TiXmlElement : public TiXmlNode
00942 {
00943 public:
00944         /// Construct an element.
00945         TiXmlElement (const char * in_value);
00946 
00947         #ifdef TIXML_USE_STL
00948         /// std::string constructor.
00949         TiXmlElement( const std::string& _value );
00950         #endif
00951 
00952         TiXmlElement( const TiXmlElement& );
00953 
00954         TiXmlElement& operator=( const TiXmlElement& base );
00955 
00956         virtual ~TiXmlElement();
00957 
00958         /** Given an attribute name, Attribute() returns the value
00959                 for the attribute of that name, or null if none exists.
00960         */
00961         const char* Attribute( const char* name ) const;
00962 
00963         /** Given an attribute name, Attribute() returns the value
00964                 for the attribute of that name, or null if none exists.
00965                 If the attribute exists and can be converted to an integer,
00966                 the integer value will be put in the return 'i', if 'i'
00967                 is non-null.
00968         */
00969         const char* Attribute( const char* name, int* i ) const;
00970 
00971         /** Given an attribute name, Attribute() returns the value
00972                 for the attribute of that name, or null if none exists.
00973                 If the attribute exists and can be converted to an double,
00974                 the double value will be put in the return 'd', if 'd'
00975                 is non-null.
00976         */
00977         const char* Attribute( const char* name, double* d ) const;
00978 
00979         /** QueryIntAttribute examines the attribute - it is an alternative to the
00980                 Attribute() method with richer error checking.
00981                 If the attribute is an integer, it is stored in 'value' and 
00982                 the call returns TIXML_SUCCESS. If it is not
00983                 an integer, it returns TIXML_WRONG_TYPE. If the attribute
00984                 does not exist, then TIXML_NO_ATTRIBUTE is returned.
00985         */      
00986         int QueryIntAttribute( const char* name, int* _value ) const;
00987         /// QueryUnsignedAttribute examines the attribute - see QueryIntAttribute().
00988         int QueryUnsignedAttribute( const char* name, unsigned* _value ) const;
00989         /** QueryBoolAttribute examines the attribute - see QueryIntAttribute(). 
00990                 Note that '1', 'true', or 'yes' are considered true, while '0', 'false'
00991                 and 'no' are considered false.
00992         */
00993         int QueryBoolAttribute( const char* name, bool* _value ) const;
00994         /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute().
00995         int QueryDoubleAttribute( const char* name, double* _value ) const;
00996         /// QueryFloatAttribute examines the attribute - see QueryIntAttribute().
00997         int QueryFloatAttribute( const char* name, float* _value ) const {
00998                 double d;
00999                 int result = QueryDoubleAttribute( name, &d );
01000                 if ( result == TIXML_SUCCESS ) {
01001                         *_value = (float)d;
01002                 }
01003                 return result;
01004         }
01005 
01006     #ifdef TIXML_USE_STL
01007         /// QueryStringAttribute examines the attribute - see QueryIntAttribute().
01008         int QueryStringAttribute( const char* name, std::string* _value ) const {
01009                 const char* cstr = Attribute( name );
01010                 if ( cstr ) {
01011                         *_value = std::string( cstr );
01012                         return TIXML_SUCCESS;
01013                 }
01014                 return TIXML_NO_ATTRIBUTE;
01015         }
01016 
01017         /** Template form of the attribute query which will try to read the
01018                 attribute into the specified type. Very easy, very powerful, but
01019                 be careful to make sure to call this with the correct type.
01020                 
01021                 NOTE: This method doesn't work correctly for 'string' types that contain spaces.
01022 
01023                 @return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE
01024         */
01025         template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const
01026         {
01027                 const TiXmlAttribute* node = attributeSet.Find( name );
01028                 if ( !node )
01029                         return TIXML_NO_ATTRIBUTE;
01030 
01031                 std::stringstream sstream( node->ValueStr() );
01032                 sstream >> *outValue;
01033                 if ( !sstream.fail() )
01034                         return TIXML_SUCCESS;
01035                 return TIXML_WRONG_TYPE;
01036         }
01037 
01038         int QueryValueAttribute( const std::string& name, std::string* outValue ) const
01039         {
01040                 const TiXmlAttribute* node = attributeSet.Find( name );
01041                 if ( !node )
01042                         return TIXML_NO_ATTRIBUTE;
01043                 *outValue = node->ValueStr();
01044                 return TIXML_SUCCESS;
01045         }
01046         #endif
01047 
01048         /** Sets an attribute of name to a given value. The attribute
01049                 will be created if it does not exist, or changed if it does.
01050         */
01051         void SetAttribute( const char* name, const char * _value );
01052 
01053     #ifdef TIXML_USE_STL
01054         const std::string* Attribute( const std::string& name ) const;
01055         const std::string* Attribute( const std::string& name, int* i ) const;
01056         const std::string* Attribute( const std::string& name, double* d ) const;
01057         int QueryIntAttribute( const std::string& name, int* _value ) const;
01058         int QueryDoubleAttribute( const std::string& name, double* _value ) const;
01059 
01060         /// STL std::string form.
01061         void SetAttribute( const std::string& name, const std::string& _value );
01062         ///< STL std::string form.
01063         void SetAttribute( const std::string& name, int _value );
01064         ///< STL std::string form.
01065         void SetDoubleAttribute( const std::string& name, double value );
01066         #endif
01067 
01068         /** Sets an attribute of name to a given value. The attribute
01069                 will be created if it does not exist, or changed if it does.
01070         */
01071         void SetAttribute( const char * name, int value );
01072 
01073         /** Sets an attribute of name to a given value. The attribute
01074                 will be created if it does not exist, or changed if it does.
01075         */
01076         void SetDoubleAttribute( const char * name, double value );
01077 
01078         /** Deletes an attribute with the given name.
01079         */
01080         void RemoveAttribute( const char * name );
01081     #ifdef TIXML_USE_STL
01082         void RemoveAttribute( const std::string& name ) {       RemoveAttribute (name.c_str ());        }       ///< STL std::string form.
01083         #endif
01084 
01085         const TiXmlAttribute* FirstAttribute() const    { return attributeSet.First(); }                ///< Access the first attribute in this element.
01086         TiXmlAttribute* FirstAttribute()                                { return attributeSet.First(); }
01087         const TiXmlAttribute* LastAttribute()   const   { return attributeSet.Last(); }         ///< Access the last attribute in this element.
01088         TiXmlAttribute* LastAttribute()                                 { return attributeSet.Last(); }
01089 
01090         /** Convenience function for easy access to the text inside an element. Although easy
01091                 and concise, GetText() is limited compared to getting the TiXmlText child
01092                 and accessing it directly.
01093         
01094                 If the first child of 'this' is a TiXmlText, the GetText()
01095                 returns the character string of the Text node, else null is returned.
01096 
01097                 This is a convenient method for getting the text of simple contained text:
01098                 @verbatim
01099                 <foo>This is text</foo>
01100                 const char* str = fooElement->GetText();
01101                 @endverbatim
01102 
01103                 'str' will be a pointer to "This is text". 
01104                 
01105                 Note that this function can be misleading. If the element foo was created from
01106                 this XML:
01107                 @verbatim
01108                 <foo><b>This is text</b></foo> 
01109                 @endverbatim
01110 
01111                 then the value of str would be null. The first child node isn't a text node, it is
01112                 another element. From this XML:
01113                 @verbatim
01114                 <foo>This is <b>text</b></foo> 
01115                 @endverbatim
01116                 GetText() will return "This is ".
01117 
01118                 WARNING: GetText() accesses a child node - don't become confused with the 
01119                                  similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are 
01120                                  safe type casts on the referenced node.
01121         */
01122         const char* GetText() const;
01123 
01124         /// Creates a new Element and returns it - the returned element is a copy.
01125         virtual TiXmlNode* Clone() const;
01126         // Print the Element to a FILE stream.
01127         virtual void Print( FILE* cfile, int depth ) const;
01128 
01129         /*      Attribtue parsing starts: next char past '<'
01130                                                  returns: next char past '>'
01131         */
01132         virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01133 
01134         virtual const TiXmlElement*     ToElement()     const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
01135         virtual TiXmlElement*           ToElement()               { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
01136 
01137         /** Walk the XML tree visiting this node and all of its children. 
01138         */
01139         virtual bool Accept( TiXmlVisitor* visitor ) const;
01140 
01141 protected:
01142 
01143         void CopyTo( TiXmlElement* target ) const;
01144         void ClearThis();       // like clear, but initializes 'this' object as well
01145 
01146         // Used to be public [internal use]
01147         #ifdef TIXML_USE_STL
01148         virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01149         #endif
01150         /*      [internal use]
01151                 Reads the "value" of the element -- another element, or text.
01152                 This should terminate with the current end tag.
01153         */
01154         const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding );
01155 
01156 private:
01157         TiXmlAttributeSet attributeSet;
01158 };
01159 
01160 
01161 /**     An XML comment.
01162 */
01163 class TiXmlComment : public TiXmlNode
01164 {
01165 public:
01166         /// Constructs an empty comment.
01167         TiXmlComment() : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {}
01168         /// Construct a comment from text.
01169         TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {
01170                 SetValue( _value );
01171         }
01172         TiXmlComment( const TiXmlComment& );
01173         TiXmlComment& operator=( const TiXmlComment& base );
01174 
01175         virtual ~TiXmlComment() {}
01176 
01177         /// Returns a copy of this Comment.
01178         virtual TiXmlNode* Clone() const;
01179         // Write this Comment to a FILE stream.
01180         virtual void Print( FILE* cfile, int depth ) const;
01181 
01182         /*      Attribtue parsing starts: at the ! of the !--
01183                                                  returns: next char past '>'
01184         */
01185         virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01186 
01187         virtual const TiXmlComment*  ToComment() const  { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
01188         virtual           TiXmlComment*  ToComment()            { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
01189 
01190         /** Walk the XML tree visiting this node and all of its children. 
01191         */
01192         virtual bool Accept( TiXmlVisitor* visitor ) const;
01193 
01194 protected:
01195         void CopyTo( TiXmlComment* target ) const;
01196 
01197         // used to be public
01198         #ifdef TIXML_USE_STL
01199         virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01200         #endif
01201 //      virtual void StreamOut( TIXML_OSTREAM * out ) const;
01202 
01203 private:
01204 
01205 };
01206 
01207 
01208 /** XML text. A text node can have 2 ways to output the next. "normal" output 
01209         and CDATA. It will default to the mode it was parsed from the XML file and
01210         you generally want to leave it alone, but you can change the output mode with 
01211         SetCDATA() and query it with CDATA().
01212 */
01213 class TiXmlText : public TiXmlNode
01214 {
01215         friend class TiXmlElement;
01216 public:
01217         /** Constructor for text element. By default, it is treated as 
01218                 normal, encoded text. If you want it be output as a CDATA text
01219                 element, set the parameter _cdata to 'true'
01220         */
01221         TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT)
01222         {
01223                 SetValue( initValue );
01224                 cdata = false;
01225         }
01226         virtual ~TiXmlText() {}
01227 
01228         #ifdef TIXML_USE_STL
01229         /// Constructor.
01230         TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT)
01231         {
01232                 SetValue( initValue );
01233                 cdata = false;
01234         }
01235         #endif
01236 
01237         TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TINYXML_TEXT )       { copy.CopyTo( this ); }
01238         TiXmlText& operator=( const TiXmlText& base )                                                           { base.CopyTo( this ); return *this; }
01239 
01240         // Write this text object to a FILE stream.
01241         virtual void Print( FILE* cfile, int depth ) const;
01242 
01243         /// Queries whether this represents text using a CDATA section.
01244         bool CDATA() const                              { return cdata; }
01245         /// Turns on or off a CDATA representation of text.
01246         void SetCDATA( bool _cdata )    { cdata = _cdata; }
01247 
01248         virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01249 
01250         virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
01251         virtual TiXmlText*       ToText()       { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
01252 
01253         /** Walk the XML tree visiting this node and all of its children. 
01254         */
01255         virtual bool Accept( TiXmlVisitor* content ) const;
01256 
01257 protected :
01258         ///  [internal use] Creates a new Element and returns it.
01259         virtual TiXmlNode* Clone() const;
01260         void CopyTo( TiXmlText* target ) const;
01261 
01262         bool Blank() const;     // returns true if all white space and new lines
01263         // [internal use]
01264         #ifdef TIXML_USE_STL
01265         virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01266         #endif
01267 
01268 private:
01269         bool cdata;                     // true if this should be input and output as a CDATA style text element
01270 };
01271 
01272 
01273 /** In correct XML the declaration is the first entry in the file.
01274         @verbatim
01275                 <?xml version="1.0" standalone="yes"?>
01276         @endverbatim
01277 
01278         TinyXml will happily read or write files without a declaration,
01279         however. There are 3 possible attributes to the declaration:
01280         version, encoding, and standalone.
01281 
01282         Note: In this version of the code, the attributes are
01283         handled as special cases, not generic attributes, simply
01284         because there can only be at most 3 and they are always the same.
01285 */
01286 class TiXmlDeclaration : public TiXmlNode
01287 {
01288 public:
01289         /// Construct an empty declaration.
01290         TiXmlDeclaration()   : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) {}
01291 
01292 #ifdef TIXML_USE_STL
01293         /// Constructor.
01294         TiXmlDeclaration(       const std::string& _version,
01295                                                 const std::string& _encoding,
01296                                                 const std::string& _standalone );
01297 #endif
01298 
01299         /// Construct.
01300         TiXmlDeclaration(       const char* _version,
01301                                                 const char* _encoding,
01302                                                 const char* _standalone );
01303 
01304         TiXmlDeclaration( const TiXmlDeclaration& copy );
01305         TiXmlDeclaration& operator=( const TiXmlDeclaration& copy );
01306 
01307         virtual ~TiXmlDeclaration()     {}
01308 
01309         /// Version. Will return an empty string if none was found.
01310         const char *Version() const                     { return version.c_str (); }
01311         /// Encoding. Will return an empty string if none was found.
01312         const char *Encoding() const            { return encoding.c_str (); }
01313         /// Is this a standalone document?
01314         const char *Standalone() const          { return standalone.c_str (); }
01315 
01316         /// Creates a copy of this Declaration and returns it.
01317         virtual TiXmlNode* Clone() const;
01318         // Print this declaration to a FILE stream.
01319         virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
01320         virtual void Print( FILE* cfile, int depth ) const {
01321                 Print( cfile, depth, 0 );
01322         }
01323 
01324         virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01325 
01326         virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
01327         virtual TiXmlDeclaration*       ToDeclaration()       { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
01328 
01329         /** Walk the XML tree visiting this node and all of its children. 
01330         */
01331         virtual bool Accept( TiXmlVisitor* visitor ) const;
01332 
01333 protected:
01334         void CopyTo( TiXmlDeclaration* target ) const;
01335         // used to be public
01336         #ifdef TIXML_USE_STL
01337         virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01338         #endif
01339 
01340 private:
01341 
01342         TIXML_STRING version;
01343         TIXML_STRING encoding;
01344         TIXML_STRING standalone;
01345 };
01346 
01347 
01348 /** Any tag that tinyXml doesn't recognize is saved as an
01349         unknown. It is a tag of text, but should not be modified.
01350         It will be written back to the XML, unchanged, when the file
01351         is saved.
01352 
01353         DTD tags get thrown into TiXmlUnknowns.
01354 */
01355 class TiXmlUnknown : public TiXmlNode
01356 {
01357 public:
01358         TiXmlUnknown() : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN )        {}
01359         virtual ~TiXmlUnknown() {}
01360 
01361         TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN )              { copy.CopyTo( this ); }
01362         TiXmlUnknown& operator=( const TiXmlUnknown& copy )                                                                             { copy.CopyTo( this ); return *this; }
01363 
01364         /// Creates a copy of this Unknown and returns it.
01365         virtual TiXmlNode* Clone() const;
01366         // Print this Unknown to a FILE stream.
01367         virtual void Print( FILE* cfile, int depth ) const;
01368 
01369         virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
01370 
01371         virtual const TiXmlUnknown*     ToUnknown()     const   { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
01372         virtual TiXmlUnknown*           ToUnknown()                             { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
01373 
01374         /** Walk the XML tree visiting this node and all of its children. 
01375         */
01376         virtual bool Accept( TiXmlVisitor* content ) const;
01377 
01378 protected:
01379         void CopyTo( TiXmlUnknown* target ) const;
01380 
01381         #ifdef TIXML_USE_STL
01382         virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01383         #endif
01384 
01385 private:
01386 
01387 };
01388 
01389 
01390 /** Always the top level node. A document binds together all the
01391         XML pieces. It can be saved, loaded, and printed to the screen.
01392         The 'value' of a document node is the xml file name.
01393 */
01394 class TiXmlDocument : public TiXmlNode
01395 {
01396 public:
01397         /// Create an empty document, that has no name.
01398         TiXmlDocument();
01399         /// Create a document with a name. The name of the document is also the filename of the xml.
01400         TiXmlDocument( const char * documentName );
01401 
01402         #ifdef TIXML_USE_STL
01403         /// Constructor.
01404         TiXmlDocument( const std::string& documentName );
01405         #endif
01406 
01407         TiXmlDocument( const TiXmlDocument& copy );
01408         TiXmlDocument& operator=( const TiXmlDocument& copy );
01409 
01410         virtual ~TiXmlDocument() {}
01411 
01412         /** Load a file using the current document value.
01413                 Returns true if successful. Will delete any existing
01414                 document data before loading.
01415         */
01416         bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
01417         /// Save a file using the current document value. Returns true if successful.
01418         bool SaveFile() const;
01419         /// Load a file using the given filename. Returns true if successful.
01420         bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
01421         /// Save a file using the given filename. Returns true if successful.
01422         bool SaveFile( const char * filename ) const;
01423         /** Load a file using the given FILE*. Returns true if successful. Note that this method
01424                 doesn't stream - the entire object pointed at by the FILE*
01425                 will be interpreted as an XML file. TinyXML doesn't stream in XML from the current
01426                 file location. Streaming may be added in the future.
01427         */
01428         bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
01429         /// Save a file using the given FILE*. Returns true if successful.
01430         bool SaveFile( FILE* ) const;
01431 
01432         #ifdef TIXML_USE_STL
01433         bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING )                   ///< STL std::string version.
01434         {
01435                 return LoadFile( filename.c_str(), encoding );
01436         }
01437         bool SaveFile( const std::string& filename ) const              ///< STL std::string version.
01438         {
01439                 return SaveFile( filename.c_str() );
01440         }
01441         #endif
01442 
01443         /** Parse the given null terminated block of xml data. Passing in an encoding to this
01444                 method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml
01445                 to use that encoding, regardless of what TinyXml might otherwise try to detect.
01446         */
01447         virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
01448 
01449         /** Get the root element -- the only top level element -- of the document.
01450                 In well formed XML, there should only be one. TinyXml is tolerant of
01451                 multiple elements at the document level.
01452         */
01453         const TiXmlElement* RootElement() const         { return FirstChildElement(); }
01454         TiXmlElement* RootElement()                                     { return FirstChildElement(); }
01455 
01456         /** If an error occurs, Error will be set to true. Also,
01457                 - The ErrorId() will contain the integer identifier of the error (not generally useful)
01458                 - The ErrorDesc() method will return the name of the error. (very useful)
01459                 - The ErrorRow() and ErrorCol() will return the location of the error (if known)
01460         */      
01461         bool Error() const                                              { return error; }
01462 
01463         /// Contains a textual (english) description of the error if one occurs.
01464         const char * ErrorDesc() const  { return errorDesc.c_str (); }
01465 
01466         /** Generally, you probably want the error string ( ErrorDesc() ). But if you
01467                 prefer the ErrorId, this function will fetch it.
01468         */
01469         int ErrorId()   const                           { return errorId; }
01470 
01471         /** Returns the location (if known) of the error. The first column is column 1, 
01472                 and the first row is row 1. A value of 0 means the row and column wasn't applicable
01473                 (memory errors, for example, have no row/column) or the parser lost the error. (An
01474                 error in the error reporting, in that case.)
01475 
01476                 @sa SetTabSize, Row, Column
01477         */
01478         int ErrorRow() const    { return errorLocation.row+1; }
01479         int ErrorCol() const    { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow()
01480 
01481         /** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol())
01482                 to report the correct values for row and column. It does not change the output
01483                 or input in any way.
01484                 
01485                 By calling this method, with a tab size
01486                 greater than 0, the row and column of each node and attribute is stored
01487                 when the file is loaded. Very useful for tracking the DOM back in to
01488                 the source file.
01489 
01490                 The tab size is required for calculating the location of nodes. If not
01491                 set, the default of 4 is used. The tabsize is set per document. Setting
01492                 the tabsize to 0 disables row/column tracking.
01493 
01494                 Note that row and column tracking is not supported when using operator>>.
01495 
01496                 The tab size needs to be enabled before the parse or load. Correct usage:
01497                 @verbatim
01498                 TiXmlDocument doc;
01499                 doc.SetTabSize( 8 );
01500                 doc.Load( "myfile.xml" );
01501                 @endverbatim
01502 
01503                 @sa Row, Column
01504         */
01505         void SetTabSize( int _tabsize )         { tabsize = _tabsize; }
01506 
01507         int TabSize() const     { return tabsize; }
01508 
01509         /** If you have handled the error, it can be reset with this call. The error
01510                 state is automatically cleared if you Parse a new XML block.
01511         */
01512         void ClearError()                                               {       error = false; 
01513                                                                                                 errorId = 0; 
01514                                                                                                 errorDesc = ""; 
01515                                                                                                 errorLocation.row = errorLocation.col = 0; 
01516                                                                                                 //errorLocation.last = 0; 
01517                                                                                         }
01518 
01519         /** Write the document to standard out using formatted printing ("pretty print"). */
01520         void Print() const                                              { Print( stdout, 0 ); }
01521 
01522         /* Write the document to a string using formatted printing ("pretty print"). This
01523                 will allocate a character array (new char[]) and return it as a pointer. The
01524                 calling code pust call delete[] on the return char* to avoid a memory leak.
01525         */
01526         //char* PrintToMemory() const; 
01527 
01528         /// Print this Document to a FILE stream.
01529         virtual void Print( FILE* cfile, int depth = 0 ) const;
01530         // [internal use]
01531         void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding );
01532 
01533         virtual const TiXmlDocument*    ToDocument()    const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
01534         virtual TiXmlDocument*          ToDocument()          { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
01535 
01536         /** Walk the XML tree visiting this node and all of its children. 
01537         */
01538         virtual bool Accept( TiXmlVisitor* content ) const;
01539 
01540 protected :
01541         // [internal use]
01542         virtual TiXmlNode* Clone() const;
01543         #ifdef TIXML_USE_STL
01544         virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
01545         #endif
01546 
01547 private:
01548         void CopyTo( TiXmlDocument* target ) const;
01549 
01550         bool error;
01551         int  errorId;
01552         TIXML_STRING errorDesc;
01553         int tabsize;
01554         TiXmlCursor errorLocation;
01555         bool useMicrosoftBOM;           // the UTF-8 BOM were found when read. Note this, and try to write.
01556 };
01557 
01558 
01559 /**
01560         A TiXmlHandle is a class that wraps a node pointer with null checks; this is
01561         an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml
01562         DOM structure. It is a separate utility class.
01563 
01564         Take an example:
01565         @verbatim
01566         <Document>
01567                 <Element attributeA = "valueA">
01568                         <Child attributeB = "value1" />
01569                         <Child attributeB = "value2" />
01570                 </Element>
01571         <Document>
01572         @endverbatim
01573 
01574         Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very 
01575         easy to write a *lot* of code that looks like:
01576 
01577         @verbatim
01578         TiXmlElement* root = document.FirstChildElement( "Document" );
01579         if ( root )
01580         {
01581                 TiXmlElement* element = root->FirstChildElement( "Element" );
01582                 if ( element )
01583                 {
01584                         TiXmlElement* child = element->FirstChildElement( "Child" );
01585                         if ( child )
01586                         {
01587                                 TiXmlElement* child2 = child->NextSiblingElement( "Child" );
01588                                 if ( child2 )
01589                                 {
01590                                         // Finally do something useful.
01591         @endverbatim
01592 
01593         And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity
01594         of such code. A TiXmlHandle checks for null     pointers so it is perfectly safe 
01595         and correct to use:
01596 
01597         @verbatim
01598         TiXmlHandle docHandle( &document );
01599         TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement();
01600         if ( child2 )
01601         {
01602                 // do something useful
01603         @endverbatim
01604 
01605         Which is MUCH more concise and useful.
01606 
01607         It is also safe to copy handles - internally they are nothing more than node pointers.
01608         @verbatim
01609         TiXmlHandle handleCopy = handle;
01610         @endverbatim
01611 
01612         What they should not be used for is iteration:
01613 
01614         @verbatim
01615         int i=0; 
01616         while ( true )
01617         {
01618                 TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement();
01619                 if ( !child )
01620                         break;
01621                 // do something
01622                 ++i;
01623         }
01624         @endverbatim
01625 
01626         It seems reasonable, but it is in fact two embedded while loops. The Child method is 
01627         a linear walk to find the element, so this code would iterate much more than it needs 
01628         to. Instead, prefer:
01629 
01630         @verbatim
01631         TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement();
01632 
01633         for( child; child; child=child->NextSiblingElement() )
01634         {
01635                 // do something
01636         }
01637         @endverbatim
01638 */
01639 class TiXmlHandle
01640 {
01641 public:
01642         /// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
01643         TiXmlHandle( TiXmlNode* _node )                                 { this->node = _node; }
01644         /// Copy constructor
01645         TiXmlHandle( const TiXmlHandle& ref )                   { this->node = ref.node; }
01646         TiXmlHandle operator=( const TiXmlHandle& ref ) { if ( &ref != this ) this->node = ref.node; return *this; }
01647 
01648         /// Return a handle to the first child node.
01649         TiXmlHandle FirstChild() const;
01650         /// Return a handle to the first child node with the given name.
01651         TiXmlHandle FirstChild( const char * value ) const;
01652         /// Return a handle to the first child element.
01653         TiXmlHandle FirstChildElement() const;
01654         /// Return a handle to the first child element with the given name.
01655         TiXmlHandle FirstChildElement( const char * value ) const;
01656 
01657         /** Return a handle to the "index" child with the given name. 
01658                 The first child is 0, the second 1, etc.
01659         */
01660         TiXmlHandle Child( const char* value, int index ) const;
01661         /** Return a handle to the "index" child. 
01662                 The first child is 0, the second 1, etc.
01663         */
01664         TiXmlHandle Child( int index ) const;
01665         /** Return a handle to the "index" child element with the given name. 
01666                 The first child element is 0, the second 1, etc. Note that only TiXmlElements
01667                 are indexed: other types are not counted.
01668         */
01669         TiXmlHandle ChildElement( const char* value, int index ) const;
01670         /** Return a handle to the "index" child element. 
01671                 The first child element is 0, the second 1, etc. Note that only TiXmlElements
01672                 are indexed: other types are not counted.
01673         */
01674         TiXmlHandle ChildElement( int index ) const;
01675 
01676         #ifdef TIXML_USE_STL
01677         TiXmlHandle FirstChild( const std::string& _value ) const                               { return FirstChild( _value.c_str() ); }
01678         TiXmlHandle FirstChildElement( const std::string& _value ) const                { return FirstChildElement( _value.c_str() ); }
01679 
01680         TiXmlHandle Child( const std::string& _value, int index ) const                 { return Child( _value.c_str(), index ); }
01681         TiXmlHandle ChildElement( const std::string& _value, int index ) const  { return ChildElement( _value.c_str(), index ); }
01682         #endif
01683 
01684         /** Return the handle as a TiXmlNode. This may return null.
01685         */
01686         TiXmlNode* ToNode() const                       { return node; } 
01687         /** Return the handle as a TiXmlElement. This may return null.
01688         */
01689         TiXmlElement* ToElement() const         { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
01690         /**     Return the handle as a TiXmlText. This may return null.
01691         */
01692         TiXmlText* ToText() const                       { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
01693         /** Return the handle as a TiXmlUnknown. This may return null.
01694         */
01695         TiXmlUnknown* ToUnknown() const         { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
01696 
01697         /** @deprecated use ToNode. 
01698                 Return the handle as a TiXmlNode. This may return null.
01699         */
01700         TiXmlNode* Node() const                 { return ToNode(); } 
01701         /** @deprecated use ToElement. 
01702                 Return the handle as a TiXmlElement. This may return null.
01703         */
01704         TiXmlElement* Element() const   { return ToElement(); }
01705         /**     @deprecated use ToText()
01706                 Return the handle as a TiXmlText. This may return null.
01707         */
01708         TiXmlText* Text() const                 { return ToText(); }
01709         /** @deprecated use ToUnknown()
01710                 Return the handle as a TiXmlUnknown. This may return null.
01711         */
01712         TiXmlUnknown* Unknown() const   { return ToUnknown(); }
01713 
01714 private:
01715         TiXmlNode* node;
01716 };
01717 
01718 
01719 /** Print to memory functionality. The TiXmlPrinter is useful when you need to:
01720 
01721         -# Print to memory (especially in non-STL mode)
01722         -# Control formatting (line endings, etc.)
01723 
01724         When constructed, the TiXmlPrinter is in its default "pretty printing" mode.
01725         Before calling Accept() you can call methods to control the printing
01726         of the XML document. After TiXmlNode::Accept() is called, the printed document can
01727         be accessed via the CStr(), Str(), and Size() methods.
01728 
01729         TiXmlPrinter uses the Visitor API.
01730         @verbatim
01731         TiXmlPrinter printer;
01732         printer.SetIndent( "\t" );
01733 
01734         doc.Accept( &printer );
01735         fprintf( stdout, "%s", printer.CStr() );
01736         @endverbatim
01737 */
01738 class TiXmlPrinter : public TiXmlVisitor
01739 {
01740 public:
01741         TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ),
01742                                          buffer(), indent( "    " ), lineBreak( "\n" ) {}
01743 
01744         virtual bool VisitEnter( const TiXmlDocument& doc );
01745         virtual bool VisitExit( const TiXmlDocument& doc );
01746 
01747         virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute );
01748         virtual bool VisitExit( const TiXmlElement& element );
01749 
01750         virtual bool Visit( const TiXmlDeclaration& declaration );
01751         virtual bool Visit( const TiXmlText& text );
01752         virtual bool Visit( const TiXmlComment& comment );
01753         virtual bool Visit( const TiXmlUnknown& unknown );
01754 
01755         /** Set the indent characters for printing. By default 4 spaces
01756                 but tab (\t) is also useful, or null/empty string for no indentation.
01757         */
01758         void SetIndent( const char* _indent )                   { indent = _indent ? _indent : "" ; }
01759         /// Query the indention string.
01760         const char* Indent()                                                    { return indent.c_str(); }
01761         /** Set the line breaking string. By default set to newline (\n). 
01762                 Some operating systems prefer other characters, or can be
01763                 set to the null/empty string for no indenation.
01764         */
01765         void SetLineBreak( const char* _lineBreak )             { lineBreak = _lineBreak ? _lineBreak : ""; }
01766         /// Query the current line breaking string.
01767         const char* LineBreak()                                                 { return lineBreak.c_str(); }
01768 
01769         /** Switch over to "stream printing" which is the most dense formatting without 
01770                 linebreaks. Common when the XML is needed for network transmission.
01771         */
01772         void SetStreamPrinting()                                                { indent = "";
01773                                                                                                           lineBreak = "";
01774                                                                                                         }       
01775         /// Return the result.
01776         const char* CStr()                                                              { return buffer.c_str(); }
01777         /// Return the length of the result string.
01778         size_t Size()                                                                   { return buffer.size(); }
01779 
01780         #ifdef TIXML_USE_STL
01781         /// Return the result.
01782         const std::string& Str()                                                { return buffer; }
01783         #endif
01784 
01785 private:
01786         void DoIndent() {
01787                 for( int i=0; i<depth; ++i )
01788                         buffer += indent;
01789         }
01790         void DoLineBreak() {
01791                 buffer += lineBreak;
01792         }
01793 
01794         int depth;
01795         bool simpleTextPrint;
01796         TIXML_STRING buffer;
01797         TIXML_STRING indent;
01798         TIXML_STRING lineBreak;
01799 };
01800 
01801 
01802 #ifdef _MSC_VER
01803 #pragma warning( pop )
01804 #endif
01805 
01806 #endif