Main Page Class Hierarchy Compound List File List Compound Members

# tinyxml.h

    00001 /*
    00002 Copyright (c) 2000 Lee Thomason (www.grinninglizard.com)
    00003
    00004 This software is provided 'as-is', without any express or implied
    00005 warranty. In no event will the authors be held liable for any
    00006 damages arising from the use of this software.
    00007
    00008 Permission is granted to anyone to use this software for any
    00009 purpose, including commercial applications, and to alter it and
    00010 redistribute it freely, subject to the following restrictions:
    00011
    00012 1. The origin of this software must not be misrepresented; you must
    00013 not claim that you wrote the original software. If you use this
    00014 software in a product, an acknowledgment in the product documentation
    00015 would be appreciated but is not required.
    00016
    00017 2. Altered source versions must be plainly marked as such, and
    00018 must not be misrepresented as being the original software.
    00019
    00020 3. This notice may not be removed or altered from any source
    00021 distribution.
    00022 */
    00023
    00024
    00025 #ifndef TINYXML_INCLUDED
    00026 #define TINYXML_INCLUDED
    00027
    00028 #pragma warning( disable : 4530 )
    00029 #pragma warning( disable : 4786 )
    00030
    00031 #include <string>
    00032 #include <stdio.h>
    00033 #include <assert.h>
    00034
    00035 class TiXmlDocument;
    00036 class TiXmlElement;
    00037 class TiXmlComment;
    00038 class TiXmlUnknown;
    00039 class TiXmlAttribute;
    00040 class TiXmlText;
    00041 class TiXmlDeclaration;
    00042
    00043
    00066 class TiXmlBase
    00067 {
    00068     friend class TiXmlNode;
    00069     friend class TiXmlElement;
    00070     friend class TiXmlDocument;
    00071
    00072   public:
    00073     TiXmlBase()                             {}
    00074     virtual ~TiXmlBase()                    {}
    00075
    00076     /*  All TinyXml classes can print themselves to a filestream.
    00077     */
    00078     virtual void Print( FILE* fp, int depth )   = 0;
    00079
    00080   protected:
    00081     /*  General parsing helper method. Takes a pointer in,
    00082         skips all the white space it finds, and returns a pointer
    00083         to the first non-whitespace data.
    00084     */
    00085     static const char* SkipWhiteSpace( const char* p );
    00086
    00087     /*  Reads an XML name into the string provided. Returns
    00088         a pointer just past the last character of the name,
    00089         or 0 if the function has an error.
    00090     */
    00091     static const char* ReadName( const char* p, std::string* name );
    00092
    00093     enum
    00094     {
    00095         TIXML_NO_ERROR = 0,
    00096         TIXML_ERROR_OPENING_FILE,
    00097         TIXML_ERROR_OUT_OF_MEMORY,
    00098         TIXML_ERROR_PARSING_ELEMENT,
    00099         TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
    00100         TIXML_ERROR_READING_ELEMENT_VALUE,
    00101         TIXML_ERROR_READING_ATTRIBUTES,
    00102         TIXML_ERROR_PARSING_EMPTY,
    00103         TIXML_ERROR_READING_END_TAG,
    00104         TIXML_ERROR_PARSING_UNKNOWN,
    00105         TIXML_ERROR_PARSING_COMMENT,
    00106         TIXML_ERROR_PARSING_DECLARATION,
    00107
    00108         TIXML_ERROR_STRING_COUNT
    00109     };
    00110     static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
    00111 };
    00112
    00113
    00120 class TiXmlNode : public TiXmlBase
    00121 {
    00122   public:
    00126     enum NodeType
    00127     {
    00128         DOCUMENT, ELEMENT, COMMENT, UNKNOWN, TEXT, DECLARATION, TYPECOUNT
    00129     };
    00130
    00131     virtual ~TiXmlNode();
    00132
    00145     const std::string& Value()  const           { return value; }
    00146
    00156     void SetValue( const std::string& _value )      { value = _value; }
    00157
    00159     void Clear();
    00160
    00162     TiXmlNode* Parent() const                   { return parent; }
    00163
    00164     TiXmlNode* FirstChild() const   { return firstChild; }
    00165     TiXmlNode* FirstChild( const std::string& value ) const;
    00166
    00167     TiXmlNode* LastChild() const    { return lastChild; }
    00168     TiXmlNode* LastChild( const std::string& value ) const;
    00169
    00186     TiXmlNode* IterateChildren( TiXmlNode* previous );
    00187
    00189     TiXmlNode* IterateChildren( const std::string& value, TiXmlNode* previous );
    00190
    00194     TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
    00195
    00199     TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
    00200
    00204     TiXmlNode* InsertAfterChild(  TiXmlNode* afterThis, const TiXmlNode& addThis );
    00205
    00209     TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
    00210
    00212     bool RemoveChild( TiXmlNode* removeThis );
    00213
    00215     TiXmlNode* PreviousSibling() const          { return prev; }
    00216
    00218     TiXmlNode* PreviousSibling( const std::string& ) const;
    00219
    00221     TiXmlNode* NextSibling() const              { return next; }
    00222
    00224     TiXmlNode* NextSibling( const std::string& ) const;
    00225
    00230     TiXmlElement* NextSiblingElement() const;
    00231
    00236     TiXmlElement* NextSiblingElement( const std::string& ) const;
    00237
    00239     TiXmlElement* FirstChildElement()   const;
    00240
    00242     TiXmlElement* FirstChildElement( const std::string& value ) const;
    00243
    00245     virtual int Type()  { return type; }
    00246
    00250     TiXmlDocument* GetDocument() const;
    00251
    00252     TiXmlDocument* ToDocument() const   { return ( type == DOCUMENT ) ? (TiXmlDocument*) this : 0; }
    00253     TiXmlElement*  ToElement() const    { return ( type == ELEMENT  ) ? (TiXmlElement*)  this : 0; }
    00254     TiXmlComment*  ToComment() const    { return ( type == COMMENT  ) ? (TiXmlComment*)  this : 0; }
    00255     TiXmlUnknown*  ToUnknown() const    { return ( type == UNKNOWN  ) ? (TiXmlUnknown*)  this : 0; }
    00256     TiXmlText*     ToText()    const    { return ( type == TEXT     ) ? (TiXmlText*)     this : 0; }
    00257     TiXmlDeclaration* ToDeclaration() const { return ( type == DECLARATION ) ? (TiXmlDeclaration*) this : 0; }
    00258
    00259     virtual TiXmlNode* Clone() const = 0;
    00260
    00261   protected:
    00262     TiXmlNode( NodeType type );
    00263     virtual const char* Parse( const char* ) = 0;
    00264
    00265     // The node is passed in by ownership. This object will delete it.
    00266     TiXmlNode* LinkEndChild( TiXmlNode* addThis );
    00267
    00268     // Figure out what is at *p, and parse it. Return a node if
    00269     // successful, and update p.
    00270     TiXmlNode* IdentifyAndParse( const char** p );
    00271
    00272     void CopyToClone( TiXmlNode* target ) const { target->value = value; }
    00273
    00274     TiXmlNode*      parent;
    00275     NodeType        type;
    00276
    00277     TiXmlNode*      firstChild;
    00278     TiXmlNode*      lastChild;
    00279
    00280     std::string     value;
    00281
    00282     TiXmlNode*      prev;
    00283     TiXmlNode*      next;
    00284 };
    00285
    00286
    00296 class TiXmlAttribute : public TiXmlBase
    00297 {
    00298     friend class TiXmlAttributeSet;
    00299
    00300   public:
    00302     TiXmlAttribute() : prev( 0 ), next( 0 ) {}
    00303
    00305     TiXmlAttribute( const std::string& _name, const std::string& _value )   : name( _name ), value( _value ), prev( 0 ), next( 0 ) {}
    00306
    00307     const std::string& Name()  const { return name; }
    00308     const std::string& Value() const { return value; }
    00309
    00310     void SetName( const std::string& _name )    { name = _name; }
    00311     void SetValue( const std::string& _value )  { value = _value; }
    00312
    00314     TiXmlAttribute* Next();
    00316     TiXmlAttribute* Previous();
    00317
    00318     bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
    00319     bool operator<( const TiXmlAttribute& rhs )  const { return name < rhs.name; }
    00320     bool operator>( const TiXmlAttribute& rhs )  const { return name > rhs.name; }
    00321
    00322     /*  [internal use]
    00323         Attribtue parsing starts: first letter of the name
    00324                          returns: the next char after the value end quote
    00325     */
    00326     const char* Parse( const char* );
    00327
    00328     // [internal use]
    00329     virtual void Print( FILE* fp, int depth );
    00330
    00331     // [internal use]
    00332     // Set the document pointer so the attribute can report errors.
    00333     void SetDocument( TiXmlDocument* doc )  { document = doc; }
    00334
    00335   private:
    00336     TiXmlDocument*  document;   // A pointer back to a document, for error reporting.
    00337     std::string     name;
    00338     std::string     value;
    00339
    00340     TiXmlAttribute* prev;
    00341     TiXmlAttribute* next;
    00342 };
    00343
    00344
    00345 /*  A class used to manage a group of attributes.
    00346     It is only used internally, both by the ELEMENT and the DECLARATION.
    00347
    00348     The set can be changed transparent to the Element and Declaration
    00349     classes that use it, but NOT transparent to the Attribute
    00350     which has to implement a next() and previous() method. Which makes
    00351     it a bit problematic and prevents the use of STL.
    00352
    00353     This version is implemented with circular lists because:
    00354         - I like circular lists
    00355         - it demonstrates some independence from the (typical) doubly linked list.
    00356 */
    00357 class TiXmlAttributeSet
    00358 {
    00359   public:
    00360     TiXmlAttributeSet();
    00361     ~TiXmlAttributeSet();
    00362
    00363     void Add( TiXmlAttribute* attribute );
    00364     void Remove( TiXmlAttribute* attribute );
    00365
    00366     TiXmlAttribute* First() const   { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
    00367     TiXmlAttribute* Last()  const   { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
    00368
    00369     TiXmlAttribute* Find( const std::string& name ) const;
    00370
    00371   private:
    00372     TiXmlAttribute sentinel;
    00373 };
    00374
    00375
    00380 class TiXmlElement : public TiXmlNode
    00381 {
    00382   public:
    00384     TiXmlElement( const std::string& value );
    00385
    00386     virtual ~TiXmlElement();
    00387
    00391     const std::string* Attribute( const std::string& name ) const;
    00392
    00396     const std::string* Attribute( const std::string& name, int* i ) const;
    00397
    00401     void SetAttribute( const std::string& name,
    00402                        const std::string& value );
    00403
    00407     void SetAttribute( const std::string& name,
    00408                        int value );
    00409
    00412     void RemoveAttribute( const std::string& name );
    00413
    00414     TiXmlAttribute* FirstAttribute()    { return attributeSet.First(); }
    00415     TiXmlAttribute* LastAttribute()     { return attributeSet.Last(); }
    00416
    00417     // [internal use] Creates a new Element and returs it.
    00418     virtual TiXmlNode* Clone() const;
    00419     // [internal use]
    00420     virtual void Print( FILE* fp, int depth );
    00421
    00422   protected:
    00423     /*  [internal use]
    00424         Attribtue parsing starts: next char past '<'
    00425                          returns: next char past '>'
    00426     */
    00427     virtual const char* Parse( const char* );
    00428     const char* ReadValue( const char* p );
    00429
    00430   private:
    00431     TiXmlAttributeSet attributeSet;
    00432 };
    00433
    00434
    00437 class TiXmlComment : public TiXmlNode
    00438 {
    00439   public:
    00441     TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {}
    00442     virtual ~TiXmlComment() {}
    00443
    00444     // [internal use] Creates a new Element and returs it.
    00445     virtual TiXmlNode* Clone() const;
    00446     // [internal use]
    00447     virtual void Print( FILE* fp, int depth );
    00448
    00449   protected:
    00450     /*  [internal use]
    00451         Attribtue parsing starts: at the ! of the !--
    00452                          returns: next char past '>'
    00453     */
    00454     virtual const char* Parse( const char* );
    00455 };
    00456
    00457
    00460 class TiXmlText : public TiXmlNode
    00461 {
    00462   public:
    00463     TiXmlText()  : TiXmlNode( TiXmlNode::TEXT ) {}
    00464     virtual ~TiXmlText() {}
    00465
    00466
    00467     // [internal use] Creates a new Element and returns it.
    00468     virtual TiXmlNode* Clone() const;
    00469     // [internal use]
    00470     virtual void Print( FILE* fp, int depth );
    00471     // [internal use]
    00472     bool Blank();   // returns true if all white space and new lines
    00473
    00474     /*  [internal use]
    00475         Attribtue parsing starts: First char of the text
    00476                          returns: next char past '>'
    00477     */
    00478     virtual const char* Parse( const char* );
    00479 };
    00480
    00481
    00495 class TiXmlDeclaration : public TiXmlNode
    00496 {
    00497   public:
    00499     TiXmlDeclaration()   : TiXmlNode( TiXmlNode::DECLARATION ) {}
    00500
    00502     TiXmlDeclaration( const std::string& version,
    00503                       const std::string& encoding,
    00504                       const std::string& standalone );
    00505
    00506     virtual ~TiXmlDeclaration() {}
    00507
    00509     const std::string& Version()        { return version; }
    00511     const std::string& Encoding()       { return encoding; }
    00513     const std::string& Standalone()     { return standalone; }
    00514
    00515     // [internal use] Creates a new Element and returs it.
    00516     virtual TiXmlNode* Clone() const;
    00517     // [internal use]
    00518     virtual void Print( FILE* fp, int depth );
    00519
    00520   protected:
    00521     //  [internal use]
    00522     //  Attribtue parsing starts: next char past '<'
    00523     //                   returns: next char past '>'
    00524
    00525     virtual const char* Parse( const char* );
    00526
    00527   private:
    00528     std::string version;
    00529     std::string encoding;
    00530     std::string standalone;
    00531 };
    00532
    00533
    00539 class TiXmlUnknown : public TiXmlNode
    00540 {
    00541   public:
    00542     TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN ) {}
    00543     virtual ~TiXmlUnknown() {}
    00544
    00545     // [internal use]
    00546     virtual TiXmlNode* Clone() const;
    00547     // [internal use]
    00548     virtual void Print( FILE* fp, int depth );
    00549
    00550   protected:
    00551     /*  [internal use]
    00552         Attribute parsing starts: First char of the text
    00553                          returns: next char past '>'
    00554     */
    00555     virtual const char* Parse( const char* );
    00556 };
    00557
    00558
    00563 class TiXmlDocument : public TiXmlNode
    00564 {
    00565   public:
    00567     TiXmlDocument();
    00569     TiXmlDocument( const std::string& documentName );
    00570
    00571     virtual ~TiXmlDocument() {}
    00572
    00577     bool LoadFile();
    00579     bool SaveFile();
    00581     bool LoadFile( const std::string& filename );
    00583     bool SaveFile( const std::string& filename );
    00584
    00586     const char* Parse( const char* );
    00587
    00589     bool Error()                        { return error; }
    00591     const std::string& ErrorDesc()      { return errorDesc; }
    00592
    00594     virtual void Print( FILE* fp, int depth = 0 );
    00596     void Print()                                        { Print( stdout, 0 ); }
    00597
    00598     // [internal use]
    00599     virtual TiXmlNode* Clone() const;
    00600     // [internal use]
    00601     void SetError( int err ) {      assert( err > 0 && err < TIXML_ERROR_STRING_COUNT );
    00602                                     error   = true;
    00603                                     errorId = err;
    00604                                     errorDesc = errorString[ errorId ]; }
    00605
    00606   private:
    00607     bool error;
    00608     int  errorId;
    00609     std::string errorDesc;
    00610 };
    00611
    00612
    00613 #endif
    00614