Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages | Examples

tinyxml.h

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

Generated on Wed Sep 5 12:54:26 2007 for DSACSS Operational Code by  doxygen 1.3.9.1