• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

spl/xml/XmlNode.h

00001 /*
00002  *  Much of this code is extracted from the tinyxml project, attributed below.
00003  */
00004 /*
00005 www.sourceforge.net/projects/tinyxml
00006 Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
00007 
00008 This software is provided 'as-is', without any express or implied
00009 warranty. In no event will the authors be held liable for any
00010 damages arising from the use of this software.
00011 
00012 Permission is granted to anyone to use this software for any
00013 purpose, including commercial applications, and to alter it and
00014 redistribute it freely, subject to the following restrictions:
00015 
00016 1. The origin of this software must not be misrepresented; you must
00017 not claim that you wrote the original software. If you use this
00018 software in a product, an acknowledgment in the product documentation
00019 would be appreciated but is not required.
00020 
00021 2. Altered source versions must be plainly marked as such, and
00022 must not be misrepresented as being the original software.
00023 
00024 3. This notice may not be removed or altered from any source distribution.
00025 */
00026 
00032 #ifndef _xmlnode_h
00033 #define _xmlnode_h
00034 
00035 #include <spl/Debug.h>
00036 #include <spl/Memory.h>
00037 #include <spl/collection/List.h>
00038 #include <spl/RefCountPtr.h>
00039 #include <spl/RefCountPtrCast.h>
00040 #include <spl/String.h>
00041 #include <spl/io/TextStream.h>
00042 #include <spl/WeakReference.h>
00043 #include <spl/xml/XmlParsingData.h>
00044 
00045 class XmlNode;
00046 class XmlDocument;
00047 class XmlElement;
00048 class XmlComment;
00049 class XmlUnknown;
00050 class XmlAttribute;
00051 class XmlText;
00052 class XmlDeclaration;
00053 class XmlNodeList;
00054 
00056 typedef RefCountPtr<XmlNode> XmlNodePtr;
00057 
00058 typedef RefCountPtrCast<XmlDocument, XmlNode, XmlNodePtr> XmlDocumentPtr;               //< Cast from XmlDocumentPtr to XmlNodePtr.
00059 typedef RefCountPtrCast<XmlElement, XmlNode, XmlNodePtr> XmlElementPtr;                 //< Cast from XmlElementPtr to XmlNodePtr.
00060 typedef RefCountPtrCast<XmlComment, XmlNode, XmlNodePtr> XmlCommentPtr;                 //< Cast from XmlCommentPtr to XmlNodePtr.
00061 typedef RefCountPtrCast<XmlUnknown, XmlNode, XmlNodePtr> XmlUnknownPtr;                 //< Cast from XmlUnknownPtr to XmlNodePtr.
00062 typedef RefCountPtrCast<XmlAttribute, XmlNode, XmlNodePtr> XmlAttributePtr;             //< Cast from XmlAttributePtr to XmlNodePtr.
00063 typedef RefCountPtrCast<XmlText, XmlNode, XmlNodePtr> XmlTextPtr;                               //< Cast from XmlTextPtr to XmlNodePtr.
00064 typedef RefCountPtrCast<XmlDeclaration, XmlNode, XmlNodePtr> XmlDeclarationPtr; //< Cast from XmlDeclarationPtr to XmlNodePtr.
00065 
00066 REGISTER_TYPEOF( 489, XmlDocumentPtr );
00067 REGISTER_TYPEOF( 491, XmlElementPtr );
00068 REGISTER_TYPEOF( 492, XmlCommentPtr );
00069 REGISTER_TYPEOF( 494, XmlUnknownPtr );
00070 REGISTER_TYPEOF( 496, XmlAttributePtr );
00071 REGISTER_TYPEOF( 499, XmlTextPtr );
00072 REGISTER_TYPEOF( 500, XmlDeclarationPtr );
00073 
00074 typedef WeakReference<XmlNode, XmlNodePtr> XmlNodeRef;                                          //< Weak ref to XmlNode.
00075 typedef WeakReference<XmlDocument, XmlDocumentPtr> XmlDocumentRef;                      //< Weak ref to XmlDocument.
00076 typedef WeakReference<XmlElement, XmlElementPtr> XmlElementRef;                         //< Weak ref to XmlElement.
00077 typedef WeakReference<XmlComment, XmlCommentPtr> XmlCommentRef;                         //<     Weak ref to XmlComment.
00078 typedef WeakReference<XmlUnknown, XmlUnknownPtr> XmlUnknownRef;                         //< Weak ref to XmlUnknown.
00079 typedef WeakReference<XmlAttribute, XmlAttributePtr> XmlAttributeRef;           //< Weak ref to XmlAttribute.
00080 typedef WeakReference<XmlText, XmlTextPtr> XmlTextRef;                                          //< Weak ref to XmlText.
00081 typedef WeakReference<XmlDeclaration, XmlDeclarationPtr> XmlDeclarationRef;     //< Weak ref to XmlDeclaration.
00082 
00083 REGISTER_TYPEOF( 502, XmlDocumentRef );
00084 REGISTER_TYPEOF( 504, XmlElementRef );
00085 REGISTER_TYPEOF( 506, XmlCommentRef );
00086 REGISTER_TYPEOF( 508, XmlUnknownRef );
00087 REGISTER_TYPEOF( 510, XmlAttributeRef );
00088 REGISTER_TYPEOF( 512, XmlTextRef );
00089 REGISTER_TYPEOF( 514, XmlDeclarationRef );
00090 
00094 class XmlNode : public IMemoryValidate
00095 {
00096 private:
00097         // copy constructor would probably need to do a deep copy, which undesireable
00098         inline XmlNode(const XmlNode& pmp) {}
00099         inline void operator =(const XmlNode& pmp) {}
00100 
00101 public:
00105         enum XmlNodeType
00106         {
00107                 DOCUMENT,
00108                 ELEMENT,
00109                 COMMENT,
00110                 UNKNOWN,
00111                 TEXT,
00112                 DECLARATION,
00113                 TYPECOUNT,
00114                 ATTRIBUTE
00115         };
00116 
00117         enum
00118         {
00119                 TIXML_NO_ERROR = 0,
00120                 TIXML_ERROR,
00121                 TIXML_ERROR_OPENING_FILE,
00122                 TIXML_ERROR_OUT_OF_MEMORY,
00123                 TIXML_ERROR_PARSING_ELEMENT,
00124                 TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
00125                 TIXML_ERROR_READING_ELEMENT_VALUE,
00126                 TIXML_ERROR_READING_ATTRIBUTES,
00127                 TIXML_ERROR_PARSING_EMPTY,
00128                 TIXML_ERROR_READING_END_TAG,
00129                 TIXML_ERROR_PARSING_UNKNOWN,
00130                 TIXML_ERROR_PARSING_COMMENT,
00131                 TIXML_ERROR_PARSING_DECLARATION,
00132                 TIXML_ERROR_DOCUMENT_EMPTY,
00133                 TIXML_ERROR_EMBEDDED_NULL,
00134                 TIXML_ERROR_PARSING_CDATA,
00135                 TIXML_ERROR_DOCUMENT_TOP_ONLY,
00136 
00137                 TIXML_ERROR_STRING_COUNT
00138         };
00139 
00140 protected:
00141         friend class XmlDocument;
00142         friend class TinyXmlParser;
00143         friend class XmlElement;
00144         
00145         XmlNode*                m_parent;
00146         XmlNodeType             m_type;
00147 
00148         XmlNodePtr              m_firstChild;
00149         XmlNodePtr              m_lastChild;
00150 
00151         StringBuffer    m_value;
00152 
00153         XmlNodePtr              m_prev;
00154         XmlNodePtr              m_next;
00155                         
00156         TiXmlCursor m_location;
00157 
00158         XmlNodeRef m_self;
00159 
00160         XmlNode( XmlNodeType _type );
00161 
00162         // Copy to the allocated object. Shared functionality between Clone, Copy constructor,
00163         // and the assignment operator.
00164         void CopyTo( XmlNode& target ) const;
00165 
00166         // Figure out what is at *p, and parse it. Returns null if it is not an xml node.
00167         XmlNodePtr Identify( const char* start, XmlEncoding encoding );
00168 
00169         virtual const char* _Parse(     const char* p, XmlParsingData* data, XmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0;
00170                                                           
00171 public:
00172         class Iterator : public IIterator<XmlNodePtr>
00173         {
00174         private:
00175                 List<XmlNodePtr> m_stack;
00176                 XmlNodePtr m_current;
00177                 
00178         public:
00179                 Iterator(XmlNodePtr root);      //< root is not iterated
00180                 Iterator(const Iterator& iter);
00181                 virtual ~Iterator();
00182                 Iterator& operator =(const Iterator iter);
00183                 
00184                 virtual bool Next();
00185                 virtual bool Prev();
00186 
00187                 virtual XmlNodePtr Current();
00188                 virtual XmlNodePtr& CurrentRef();
00189         };
00190         
00191         virtual ~XmlNode();
00192         
00205         inline const StringPtr Value() const 
00206         { 
00207                 return m_value.ToString();
00208         }
00209 
00210         virtual String Name() const = 0;
00211         
00221         inline void SetValue(const String& _value) 
00222         { 
00223                 m_value = _value;
00224         }
00225 
00227         void Clear();
00228 
00230         inline XmlNodePtr ParentNode() const
00231         { 
00232                 return NULL == m_parent ? XmlNodePtr() : m_parent->m_self; 
00233         }
00234         
00235         virtual RefCountPtr<XmlNodeList> ChildNodes() const;
00236 
00238         inline XmlNodePtr FirstChild() const
00239         {
00240                 return m_firstChild; 
00241         }
00242         
00244         XmlNodePtr FirstChild( const String& value ) const;
00245         
00247         inline XmlNodePtr LastChild() const
00248         { 
00249                 return m_lastChild; 
00250         }
00251                 
00253         XmlNodePtr LastChild( const String& value ) const;
00254 
00255         XmlNodePtr Child(int index) const;
00256 
00269         void AppendChild( XmlNodePtr addThis );
00270 
00274         void InsertBefore( XmlNodePtr beforeThis, XmlNodePtr addThis );
00275 
00279         void InsertAfter( XmlNodePtr afterThis, XmlNodePtr addThis );
00280 
00284         void ReplaceChild( XmlNodePtr replaceThis, XmlNodePtr withThis );
00285 
00287         bool RemoveChild( XmlNodePtr removeThis );
00288 
00289         virtual RefCountPtr<XmlNodeList> Decendants();
00290         
00292         inline XmlNodePtr PreviousSibling()             
00293         { 
00294                 return m_prev; 
00295         }
00296         
00298         XmlNodePtr PreviousSibling( const String& );
00299 
00301         inline XmlNodePtr NextSibling()                         
00302         { 
00303                 return m_next; 
00304         }
00305         
00307         XmlNodePtr NextSibling( const String& );
00308 
00313         XmlElementPtr NextSiblingElement();
00314 
00319         XmlElementPtr NextSiblingElement( const String& );
00320 
00322         XmlElementPtr FirstChildElement();
00323 
00325         XmlElementPtr FirstChildElement( const String& _value );
00326 
00331         inline XmlNodeType NodeType() const     
00332         { 
00333                 return m_type; 
00334         }
00335 
00339         XmlDocumentPtr GetDocument();
00340 
00342         inline bool HasChildNodes() const
00343         { 
00344                 return m_firstChild.IsNotNull(); 
00345         }
00346         
00348         virtual XmlNodePtr Clone() const = 0;
00349 
00350         virtual StringPtr InnerText() const;
00351 
00353         RefCountPtr<XmlNodeList> SelectNodes(const String& xpath);
00354 
00356         XmlNodePtr SelectSingleNode(const String& xpath);
00357 
00376         inline int Row() const                  { return m_location.row + 1; }
00377         inline int Column() const               { return m_location.col + 1; }  
00378 
00379         virtual XmlDocumentPtr    ToDocument()    const; 
00380         virtual XmlElementPtr     ToElement()     const; 
00381         virtual XmlCommentPtr     ToComment()     const; 
00382         virtual XmlUnknownPtr     ToUnknown()     const; 
00383         virtual XmlTextPtr        ToText()        const; 
00384         virtual XmlDeclarationPtr ToDeclaration() const; 
00385 
00386         inline bool IsDocument()    const { return m_type == DOCUMENT; }
00387         inline bool IsElement()     const { return m_type == ELEMENT; }
00388         inline bool IsComment()     const { return m_type == COMMENT; }
00389         inline bool IsUnknown()     const { return m_type == UNKNOWN; }
00390         inline bool IsText()        const { return m_type == TEXT; }
00391         inline bool IsDeclaration() const { return m_type == DECLARATION; }
00392         inline bool IsAttribute() const { return m_type == ATTRIBUTE; }
00393 
00394         inline StringPtr OuterXml() const { return ToString(); }
00395         virtual StringPtr InnerXml() const;
00396 
00397         virtual StringPtr ToString() const = 0;
00398         virtual void WriteTo(TextWriter& writer) const = 0;
00399         
00400         inline Iterator Begin()
00401         {
00402                 return Iterator(m_self);
00403         }
00404 
00405 #ifdef DEBUG
00406         virtual void ValidateMem() const;
00407         virtual void CheckMem() const;
00408 #endif
00409 };
00410 
00411 REGISTER_TYPEOF( 520, XmlNode );
00412 
00415 #endif