PixelLightAPI  .
XmlNode.h
Go to the documentation of this file.
00001 /*********************************************************\
00002  *  File: XmlNode.h                                      *
00003  *
00004  *  Copyright (C) 2002-2012 The PixelLight Team (http://www.pixellight.org/)
00005  *
00006  *  This file is part of PixelLight.
00007  *
00008  *  PixelLight is free software: you can redistribute it and/or modify
00009  *  it under the terms of the GNU Lesser General Public License as published by
00010  *  the Free Software Foundation, either version 3 of the License, or
00011  *  (at your option) any later version.
00012  *
00013  *  PixelLight is distributed in the hope that it will be useful,
00014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00016  *  GNU Lesser General Public License for more details.
00017  *
00018  *  You should have received a copy of the GNU Lesser General Public License
00019  *  along with PixelLight. If not, see <http://www.gnu.org/licenses/>.
00020 \*********************************************************/
00021 
00022 
00023 #ifndef __PLCORE_XML_NODE_H__
00024 #define __PLCORE_XML_NODE_H__
00025 #pragma once
00026 
00027 
00028 //[-------------------------------------------------------]
00029 //[ Includes                                              ]
00030 //[-------------------------------------------------------]
00031 #include "PLCore/Xml/XmlBase.h"
00032 
00033 
00034 //[-------------------------------------------------------]
00035 //[ Namespace                                             ]
00036 //[-------------------------------------------------------]
00037 namespace PLCore {
00038 
00039 
00040 //[-------------------------------------------------------]
00041 //[ Forward declarations                                  ]
00042 //[-------------------------------------------------------]
00043 class XmlText;
00044 class XmlUnknown;
00045 class XmlComment;
00046 class XmlElement;
00047 class XmlDocument;
00048 class XmlDeclaration;
00049 
00050 
00051 //[-------------------------------------------------------]
00052 //[ Classes                                               ]
00053 //[-------------------------------------------------------]
00054 /**
00055 *  @brief
00056 *    Abstract XML node
00057 */
00058 class XmlNode : public XmlBase {
00059 
00060 
00061     //[-------------------------------------------------------]
00062     //[ Public definitions                                    ]
00063     //[-------------------------------------------------------]
00064     public:
00065         /**
00066         *  @brief
00067         *    The supported types of XML nodes. (All the
00068         *    unsupported types are picked up by 'Unknown'.)
00069         */
00070         enum ENodeType {
00071             Document,       /**< Document */
00072             Element,        /**< Element */
00073             Comment,        /**< Comment */
00074             Unknown,        /**< Unknown */
00075             Text,           /**< Text */
00076             Declaration,    /**< Declaration */
00077             NumOfTypes      /**< Number of types */
00078         };
00079 
00080 
00081     //[-------------------------------------------------------]
00082     //[ Public functions                                      ]
00083     //[-------------------------------------------------------]
00084     public:
00085         /**
00086         *  @brief
00087         *    Destructor
00088         */
00089         PLCORE_API virtual ~XmlNode();
00090 
00091         /**
00092         *  @brief
00093         *    The meaning of 'value' changes for the specific type of 'XmlNode'
00094         *
00095         *  @return
00096         *    Node value
00097         *
00098         *  @remarks
00099         *    @verbatim
00100         *    Document:  Filename of the XML file
00101         *    Element:   Name of the element
00102         *    Comment:   The comment text
00103         *    Unknown:   The tag contents
00104         *    Text:      The text string
00105         *    @endverbatim
00106         *    The subclasses will wrap this function.
00107         */
00108         inline String GetValue() const;
00109 
00110         /**
00111         *  @brief
00112         *    Changes the value of the node
00113         *
00114         *  @param[in] sValue
00115         *    New node value
00116         *
00117         *  @see
00118         *    - GetValue()
00119         */
00120         inline void SetValue(const String &sValue);
00121 
00122         /**
00123         *  @brief
00124         *    Delete all the children of this node
00125         *
00126         *  @note
00127         *    - Does not affect 'this'
00128         */
00129         PLCORE_API void Clear();
00130 
00131         /**
00132         *  @brief
00133         *    One step up the DOM
00134         *
00135         *  @return
00136         *    The parent node, a null pointer on error
00137         */
00138         inline XmlNode *GetParent();
00139         inline const XmlNode *GetParent() const;
00140 
00141         /**
00142         *  @brief
00143         *    Returns the first child of this node
00144         *
00145         *  @return
00146         *    The first child of this node, a null pointer if there are no children
00147         */
00148         inline XmlNode *GetFirstChild();
00149         inline const XmlNode *GetFirstChild() const;
00150 
00151         /**
00152         *  @brief
00153         *    Returns the first child of this node with the matching 'value'
00154         *
00155         *  @param[in] sValue
00156         *    Value to look for
00157         *
00158         *  @return
00159         *    The first child of this node with the matching 'value', a null pointer if none found
00160         */
00161         PLCORE_API XmlNode *GetFirstChild(const String &sValue);
00162         PLCORE_API const XmlNode *GetFirstChild(const String &sValue) const;
00163 
00164         /**
00165         *  @brief
00166         *    Returns the last child of this node
00167         *
00168         *  @return
00169         *    The last child of this node, a null pointer if there are no children
00170         */
00171         inline XmlNode *GetLastChild();
00172         inline const XmlNode *GetLastChild() const;
00173 
00174         /**
00175         *  @brief
00176         *    Returns the last child of this node with the matching 'value'
00177         *
00178         *  @param[in] sValue
00179         *    Value to look for
00180         *
00181         *  @return
00182         *    The last child of this node with the matching 'value', a null pointer if none found
00183         */
00184         PLCORE_API XmlNode *GetLastChild(const String &sValue);
00185         PLCORE_API const XmlNode *GetLastChild(const String &sValue) const;
00186 
00187         /**
00188         *  @brief
00189         *    An alternate way to walk the children of a node
00190         *
00191         *  @param[in] pPrevious
00192         *    Previous node, if a null pointer the first child node is returned
00193         *
00194         *  @return
00195         *    Next node, a null pointer if there's no next node
00196         *
00197         *  @remarks
00198         *    One way to iterate over nodes is:
00199         *    @verbatim
00200         *    for (XmlNode *pChild=pParent->GetFirstChild(); pChild; pChild=Child->GetNextSibling())
00201         *    @endverbatim
00202         *
00203         *    'IterateChildren()' does the same thing with the syntax:
00204         *    @verbatim
00205         *    XmlNode *pChild = pParent->IterateChildren(pChild);
00206         *    while (pChild)
00207         *    @endverbatim
00208         *
00209         *    'IterateChildren()' takes the previous child as input and finds
00210         *    the next one. If the previous child is a null pointer, it returns the
00211         *    first. 'IterateChildren()' will return a null pointer when done.
00212         */
00213         inline XmlNode *IterateChildren(XmlNode *pPrevious);
00214         inline const XmlNode *IterateChildren(const XmlNode *pPrevious) const;
00215 
00216         /**
00217         *  @brief
00218         *    This flavor of 'IterateChildren()' searches for children with a particular 'value'
00219         *
00220         *  @param[in] sValue
00221         *    Value to look for
00222         *  @param[in] pPrevious
00223         *    Previous node, if a null pointer the first child node is returned
00224         *
00225         *  @return
00226         *    Next node, a null pointer if there's no next node
00227         */
00228         inline XmlNode *IterateChildren(const String &sValue, XmlNode *pPrevious);
00229         inline const XmlNode *IterateChildren(const String &sValue, const XmlNode *pPrevious) const;
00230 
00231         /**
00232         *  @brief
00233         *    Add a new node related to this (adds a child past the last child)
00234         *
00235         *  @param[in] cAddThis
00236         *    Node to insert
00237         *
00238         *  @return
00239         *    Returns a pointer to the new object or a null pointer if an error occurred
00240         */
00241         PLCORE_API XmlNode *InsertEndChild(const XmlNode &cAddThis);
00242 
00243         /**
00244         *  @brief
00245         *    Add a new node related to this (adds a child past the last child)
00246         *
00247         *  @param[in] cAddThis
00248         *    Node to add
00249         *
00250         *  @return
00251         *    Pointer to the given 'cAddThis', a null pointer on error (on error, 'cAddThis' will be deleted)
00252         *
00253         *  @remarks
00254         *    The node to be added is passed by reference, and will be henceforth owned
00255         *    (and deleted) by the XML implementation. This method is efficient and avoids
00256         *    an extra copy, but should be used with care as it uses a different memory
00257         *    model than the other insert functions.
00258         */
00259         PLCORE_API XmlNode *LinkEndChild(XmlNode &cAddThis);
00260 
00261         /**
00262         *  @brief
00263         *    Add a new node related to this (adds a child before the specified child)
00264         *
00265         *  @param[in] cBeforeThis
00266         *    Node before this insertion
00267         *  @param[in] cAddThis
00268         *    Node to insert
00269         *
00270         *  @return
00271         *    Returns a pointer to the new object or a null pointer if an error occurred
00272         */
00273         PLCORE_API XmlNode *InsertBeforeChild(XmlNode &cBeforeThis, const XmlNode &cAddThis);
00274 
00275         /**
00276         *  @brief
00277         *    Add a new node related to this (adds a child after the specified child)
00278         *
00279         *  @param[in] cAfterThis
00280         *    Node after this insertion
00281         *  @param[in] cAddThis
00282         *    Node to insert
00283         *
00284         *  @return
00285         *    Returns a pointer to the new object or a null pointer if an error occurred
00286         */
00287         PLCORE_API XmlNode *InsertAfterChild(XmlNode &cAfterThis, const XmlNode &cAddThis);
00288 
00289         /**
00290         *  @brief
00291         *    Replace a child of this node
00292         *
00293         *  @param[in] cReplaceThis
00294         *    Node which should be replaced (on success, destroyed automatically)
00295         *  @param[in] cWithThis
00296         *    New node replacing the old
00297         *
00298         *  @return
00299         *    Returns a pointer to the new object or a null pointer if an error occurred
00300         */
00301         PLCORE_API XmlNode *ReplaceChild(XmlNode &cReplaceThis, const XmlNode &cWithThis);
00302 
00303         /**
00304         *  @brief
00305         *    Delete a child of this node
00306         *
00307         *  @param[in] cRemoveThis
00308         *    Node to remove (on success, destroyed automatically)
00309         *
00310         *  @return
00311         *    'true' if all went fine, else 'false'
00312         */
00313         PLCORE_API bool RemoveChild(XmlNode &cRemoveThis);
00314 
00315         /**
00316         *  @brief
00317         *    Navigate to a sibling node
00318         *
00319         *  @return
00320         *    The sibling node, a null pointer if there's no sibling node
00321         */
00322         inline XmlNode *GetPreviousSibling();
00323         inline const XmlNode *GetPreviousSibling() const;
00324 
00325         /**
00326         *  @brief
00327         *    Navigate to a sibling node with the given 'value'
00328         *
00329         *  @param[in] sValue
00330         *    Value to look for
00331         *
00332         *  @return
00333         *    The sibling node, a null pointer if there's no sibling node
00334         */
00335         PLCORE_API XmlNode *GetPreviousSibling(const String &sValue);
00336         PLCORE_API const XmlNode *GetPreviousSibling(const String &sValue) const;
00337 
00338         /**
00339         *  @brief
00340         *    Navigate to a sibling node
00341         *
00342         *  @return
00343         *    The sibling node, a null pointer if there's no sibling node
00344         */
00345         inline XmlNode *GetNextSibling();
00346         inline const XmlNode *GetNextSibling() const;
00347 
00348         /**
00349         *  @brief
00350         *    Navigate to a sibling node with the given 'value'
00351         *
00352         *  @param[in] sValue
00353         *    Value to look for
00354         *
00355         *  @return
00356         *    The sibling node, a null pointer if there's no sibling node
00357         */
00358         PLCORE_API XmlNode *GetNextSibling(const String &sValue);
00359         PLCORE_API const XmlNode *GetNextSibling(const String &sValue) const;
00360 
00361         /**
00362         *  @brief
00363         *    Convenience function to get through elements
00364         *
00365         *  @remarks
00366         *    Calls 'NextSibling()' and 'ToElement()'. Will skip all non-element nodes.
00367         *
00368         *  @return
00369         *    Returns a null pointer if there is not another element
00370         */
00371         inline XmlElement *GetNextSiblingElement();
00372         PLCORE_API const XmlElement *GetNextSiblingElement() const;
00373 
00374         /**
00375         *  @brief
00376         *    Convenience function to get through elements
00377         *
00378         *  @param[in] sValue
00379         *    Value to look for
00380         *
00381         *  @remarks
00382         *    Calls 'NextSibling()' and 'ToElement()'. Will skip all non-element nodes.
00383         *
00384         *  @return
00385         *    Returns a null pointer if there is not another element
00386         */
00387         PLCORE_API XmlElement *GetNextSiblingElement(const String &sValue);
00388         PLCORE_API const XmlElement *GetNextSiblingElement(const String &sValue) const;
00389 
00390         /**
00391         *  @brief
00392         *    Convenience function to get through elements
00393         *
00394         *  @return
00395         *    Returns a null pointer if there is not another element
00396         */
00397         inline XmlElement *GetFirstChildElement();
00398         PLCORE_API const XmlElement *GetFirstChildElement() const;
00399 
00400         /**
00401         *  @brief
00402         *    Convenience function to get through elements
00403         *
00404         *  @param[in] sValue
00405         *    Value to look for
00406         *
00407         *  @return
00408         *    Returns a null pointer if there is not another element
00409         */
00410         inline XmlElement *GetFirstChildElement(const String &sValue);
00411         PLCORE_API const XmlElement *GetFirstChildElement(const String &sValue) const;
00412 
00413         /**
00414         *  @brief
00415         *    Query the type (as an enumerated value, above) of this node
00416         *
00417         *  @return
00418         *    Type of this node
00419         */
00420         inline ENodeType GetType() const;
00421 
00422         /**
00423         *  @brief
00424         *    Return a pointer to the document this node lives in
00425         *
00426         *  @return
00427         *    Pointer to the document this node lives in, a null pointer if not in a document
00428         */
00429         inline XmlDocument *GetDocument();
00430         PLCORE_API const XmlDocument *GetDocument() const;
00431 
00432         /**
00433         *  @brief
00434         *    Returns true if this node has no children
00435         *
00436         *  @return
00437         *    'true' if this node has no children, else 'false'
00438         */
00439         inline bool NoChildren() const;
00440 
00441         /**
00442         *  @brief
00443         *    Cast functions, will return a null pointer if the given node is not from the requested type
00444         */
00445         inline XmlDocument *ToDocument();
00446         inline const XmlDocument *ToDocument() const;
00447         inline XmlElement *ToElement();
00448         inline const XmlElement *ToElement() const;
00449         inline XmlComment *ToComment();
00450         inline const XmlComment *ToComment() const;
00451         inline XmlUnknown *ToUnknown();
00452         inline const XmlUnknown *ToUnknown() const;
00453         inline XmlText *ToText();
00454         inline const XmlText *ToText() const;
00455         inline XmlDeclaration *ToDeclaration();
00456         inline const XmlDeclaration *ToDeclaration() const;
00457 
00458 
00459     //[-------------------------------------------------------]
00460     //[ Public virtual XmlNode functions                      ]
00461     //[-------------------------------------------------------]
00462     public:
00463         /**
00464         *  @brief
00465         *    Create an exact duplicate of this node and return it
00466         *
00467         *  @return
00468         *    The clone, a null pointer on error
00469         *
00470         *  @note
00471         *    - The memory must be deleted by the caller
00472         */
00473         virtual XmlNode *Clone() const = 0;
00474 
00475 
00476     //[-------------------------------------------------------]
00477     //[ Protected functions                                   ]
00478     //[-------------------------------------------------------]
00479     protected:
00480         /**
00481         *  @brief
00482         *    Constructor
00483         *
00484         *  @param[in] nType
00485         *    Type of the node
00486         */
00487         XmlNode(ENodeType nType);
00488 
00489         /**
00490         *  @brief
00491         *    Figure out what is at *pszData, and parse it
00492         *
00493         *  @param[in] pszData
00494         *    Start position
00495         *  @param[in] nEncoding
00496         *    Encoding
00497         *
00498         *  @return
00499         *    Returns a null pointer if it is not an XML node, else it returns a created node instance (you're responsible for it's destruction)
00500         */
00501         XmlNode *Identify(const char *pszData, EEncoding nEncoding);
00502 
00503 
00504     //[-------------------------------------------------------]
00505     //[ Protected data                                        ]
00506     //[-------------------------------------------------------]
00507     protected:
00508         XmlNode   *m_pParent;           /**< Parent node, can be a null pointer */
00509         ENodeType  m_nType;             /**< Type of the node */
00510         XmlNode   *m_pFirstChild;       /**< First child, can be a null pointer */
00511         XmlNode   *m_pLastChild;        /**< Last child, can be a null pointer */
00512         String     m_sValue;            /**< Value */
00513         XmlNode   *m_pPreviousSibling;  /**< Previous sibling, can be a null pointer */
00514         XmlNode   *m_pNextSibling;      /**< Previous sibling, can be a null pointer */
00515 
00516 
00517     //[-------------------------------------------------------]
00518     //[ Private functions                                     ]
00519     //[-------------------------------------------------------]
00520     private:
00521         /**
00522         *  @brief
00523         *    Copy constructor
00524         *
00525         *  @param[in] cSource
00526         *    Source to copy from
00527         */
00528         XmlNode(const XmlNode &cSource);
00529 
00530         /**
00531         *  @brief
00532         *    Copy operator
00533         *
00534         *  @param[in] cSource
00535         *    Source to copy from
00536         *
00537         *  @return
00538         *    Reference to this instance
00539         */
00540         XmlNode &operator =(const XmlNode &cSource);
00541 
00542 
00543 };
00544 
00545 
00546 //[-------------------------------------------------------]
00547 //[ Namespace                                             ]
00548 //[-------------------------------------------------------]
00549 } // PLCore
00550 
00551 
00552 //[-------------------------------------------------------]
00553 //[ Implementation                                        ]
00554 //[-------------------------------------------------------]
00555 #include "PLCore/Xml/XmlNode.inl"
00556 
00557 
00558 #endif // __PLCORE_XML_NODE_H__


PixelLight PixelLight 0.9.11-R1
Copyright (C) 2002-2012 by The PixelLight Team
Last modified Thu Feb 23 2012 14:09:02
The content of this PixelLight document is published under the
Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported