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 

Generated at Sun Aug 26 20:37:31 2001 for TinyXml by doxygen1.2.10 written by Dimitri van Heesch, © 1997-2001