00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
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     
00077 
00078     virtual void Print( FILE* fp, int depth )   = 0;
00079 
00080   protected:
00081     
00082 
00083 
00084 
00085     static const char* SkipWhiteSpace( const char* p );
00086 
00087     
00088 
00089 
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     
00266     TiXmlNode* LinkEndChild( TiXmlNode* addThis );
00267 
00268     
00269     
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     
00323 
00324 
00325   
00326     const char* Parse( const char* );
00327 
00328     
00329     virtual void Print( FILE* fp, int depth );
00330 
00331     
00332     
00333     void SetDocument( TiXmlDocument* doc )  { document = doc; }
00334 
00335   private:
00336     TiXmlDocument*  document;   
00337     std::string     name;
00338     std::string     value;
00339 
00340     TiXmlAttribute* prev;
00341     TiXmlAttribute* next;
00342 };
00343 
00344 
00345 
00346 
00347 
00348 
00349 
00350 
00351 
00352 
00353 
00354 
00355 
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     
00418     virtual TiXmlNode* Clone() const;
00419     
00420     virtual void Print( FILE* fp, int depth );
00421 
00422   protected:
00423     
00424 
00425 
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     
00445     virtual TiXmlNode* Clone() const;
00446     
00447     virtual void Print( FILE* fp, int depth );
00448 
00449   protected:
00450     
00451 
00452 
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     
00468     virtual TiXmlNode* Clone() const;
00469     
00470     virtual void Print( FILE* fp, int depth );
00471     
00472     bool Blank();   
00473 
00474     
00475 
00476 
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     
00516     virtual TiXmlNode* Clone() const;
00517     
00518     virtual void Print( FILE* fp, int depth );
00519 
00520   protected:
00521     
00522     
00523     
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     
00546     virtual TiXmlNode* Clone() const;
00547     
00548     virtual void Print( FILE* fp, int depth );
00549 
00550   protected:
00551     
00552 
00553 
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     
00599     virtual TiXmlNode* Clone() const;
00600     
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