PixelLightAPI  .
XmlElement.h
Go to the documentation of this file.
00001 /*********************************************************\
00002  *  File: XmlElement.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_ELEMENT_H__
00024 #define __PLCORE_XML_ELEMENT_H__
00025 #pragma once
00026 
00027 
00028 //[-------------------------------------------------------]
00029 //[ Includes                                              ]
00030 //[-------------------------------------------------------]
00031 #include "PLCore/Xml/XmlNode.h"
00032 #include "PLCore/Xml/XmlAttribute.h"
00033 
00034 
00035 //[-------------------------------------------------------]
00036 //[ Namespace                                             ]
00037 //[-------------------------------------------------------]
00038 namespace PLCore {
00039 
00040 
00041 //[-------------------------------------------------------]
00042 //[ Classes                                               ]
00043 //[-------------------------------------------------------]
00044 /**
00045 *  @brief
00046 *    The XML element is a container class
00047 *
00048 *  @remarks
00049 *    An element has a value, the element name, and can contain other elements, text,
00050 *    comments, and unknowns. Elements also contain an arbitrary number of attributes.
00051 */
00052 class XmlElement : public XmlNode {
00053 
00054 
00055     //[-------------------------------------------------------]
00056     //[ Friends                                               ]
00057     //[-------------------------------------------------------]
00058     friend class XmlNode;
00059 
00060 
00061     //[-------------------------------------------------------]
00062     //[ Public functions                                      ]
00063     //[-------------------------------------------------------]
00064     public:
00065         /**
00066         *  @brief
00067         *    Constructor
00068         *
00069         *  @param[in] sValue
00070         *    Value of this element (value = element tag name)
00071         */
00072         PLCORE_API XmlElement(const String &sValue);
00073 
00074         /**
00075         *  @brief
00076         *    Copy constructor
00077         *
00078         *  @param[in] cSource
00079         *    Source to copy from
00080         */
00081         PLCORE_API XmlElement(const XmlElement &cSource);
00082 
00083         /**
00084         *  @brief
00085         *    Destructor
00086         */
00087         PLCORE_API virtual ~XmlElement();
00088 
00089         /**
00090         *  @brief
00091         *    Copy operator
00092         *
00093         *  @param[in] cSource
00094         *    Source to copy from
00095         *
00096         *  @return
00097         *    Reference to this instance
00098         */
00099         PLCORE_API XmlElement &operator =(const XmlElement &cSource);
00100 
00101         /**
00102         *  @brief
00103         *    Given an attribute name, 'GetAttribute()' returns the value
00104         *    for the attribute of that name, or empty string if none exists
00105         *
00106         *  @param[in] sName
00107         *    Attribute name
00108         *
00109         *  @return
00110         *    Attribute value, empty on error
00111         */
00112         PLCORE_API String GetAttribute(const String &sName) const;
00113 
00114         /**
00115         *  @brief
00116         *    Given an attribute name, 'GetAttribute()' returns the value
00117         *    for the attribute of that name, or empty string if none exists
00118         *
00119         *  @param[in]  sName
00120         *    Attribute name
00121         *  @param[out] pnValue
00122         *    If not a null pointer, this variable will receive the integer value - if the attribute
00123         *    value can be converted into an integer, if not, this variable is not touched
00124         *
00125         *  @return
00126         *    Attribute value, empty on error
00127         *
00128         *  @remarks
00129         *    If the attribute exists and can be converted to an integer,
00130         *    the integer value will be put in the return 'pnValue', if 'pnValue'
00131         *    is not a null pointer.
00132         */
00133         PLCORE_API String GetAttribute(const String &sName, int *pnValue) const;
00134 
00135         /**
00136         *  @brief
00137         *    Given an attribute name, 'GetAttribute()' returns the value
00138         *    for the attribute of that name, or empty string if none exists
00139         *
00140         *  @param[in]  sName
00141         *    Attribute name
00142         *  @param[out] pdValue
00143         *    If not a null pointer, this variable will receive the double value - if the attribute
00144         *    value can be converted into a double, if not, this variable is not touched
00145         *
00146         *  @return
00147         *    Attribute value, empty on error
00148         *
00149         *  @remarks
00150         *    If the attribute exists and can be converted to an double,
00151         *    the double value will be put in the return 'pdValue', if 'pdValue'
00152         *    is not a null pointer.
00153         */
00154         PLCORE_API String GetAttribute(const String &sName, double *pdValue) const;
00155 
00156         /**
00157         *  @brief
00158         *    Examines the attribute
00159         *
00160         *  @param[in]  sName
00161         *    Attribute name
00162         *  @param[out] pnValue
00163         *    If not a null pointer, this variable will receive the integer value - if the attribute
00164         *    value can be converted into an integer, if not, this variable is not touched
00165         *
00166         *  @return
00167         *    'Success' if all went fine, 'WrongType' if value is not an integer and
00168         *    'NoAttribute' if the attribute does not exist
00169         *
00170         *  @note
00171         *     - This function is an alternative to the 'GetAttribute()' function with richer
00172         *       error checking.
00173         */
00174         PLCORE_API EQueryResult QueryIntAttribute(const String &sName, int *pnValue) const;
00175 
00176         /**
00177         *  @brief
00178         *    Examines the attribute
00179         *
00180         *  @param[in]  sName
00181         *    Attribute name
00182         *  @param[out] pfValue
00183         *    If not a null pointer, this variable will receive the float value - if the attribute
00184         *    value can be converted into a float, if not, this variable is not touched
00185         *
00186         *  @return
00187         *    'Success' if all went fine, 'WrongType' if value is not a float and
00188         *    'NoAttribute' if the attribute does not exist
00189         *
00190         *  @see
00191         *    - QueryIntAttribute()
00192         */
00193         PLCORE_API EQueryResult QueryFloatAttribute(const String &sName, float *pfValue) const;
00194 
00195         /**
00196         *  @brief
00197         *    Examines the attribute
00198         *
00199         *  @param[in]  sName
00200         *    Attribute name
00201         *  @param[out] pdValue
00202         *    If not a null pointer, this variable will receive the double value - if the attribute
00203         *    value can be converted into a double, if not, this variable is not touched
00204         *
00205         *  @return
00206         *    'Success' if all went fine, 'WrongType' if value is not a double and
00207         *    'NoAttribute' if the attribute does not exist
00208         *
00209         *  @see
00210         *    - QueryIntAttribute()
00211         */
00212         PLCORE_API EQueryResult QueryDoubleAttribute(const String &sName, double *pdValue) const;
00213 
00214         /**
00215         *  @brief
00216         *    Sets an attribute of name to a given value
00217         *
00218         *  @param[in] sName
00219         *    Attribute name
00220         *  @param[in] sValue
00221         *    Attribute value
00222         *
00223         *  @remarks
00224         *    The attribute will be created if it does not exist, or changed if it does.
00225         */
00226         PLCORE_API void SetAttribute(const String &sName, const String &sValue);
00227 
00228         /**
00229         *  @brief
00230         *    Sets an attribute of name to a given value
00231         *
00232         *  @param[in] sName
00233         *    Attribute name
00234         *  @param[in] nValue
00235         *    Attribute value
00236         *
00237         *  @remarks
00238         *    The attribute will be created if it does not exist, or changed if it does.
00239         */
00240         PLCORE_API void SetAttribute(const String &sName, int nValue);
00241 
00242         /**
00243         *  @brief
00244         *    Sets an attribute of name to a given value
00245         *
00246         *  @param[in] sName
00247         *    Attribute name
00248         *  @param[in] dValue
00249         *    Attribute value
00250         *
00251         *  @remarks
00252         *    The attribute will be created if it does not exist, or changed if it does.
00253         */
00254         PLCORE_API void SetDoubleAttribute(const String &sName, double dValue);
00255 
00256         /**
00257         *  @brief
00258         *    Deletes an attribute with the given name
00259         *
00260         *  @param[in] sName
00261         *    Name of the attribute to remove
00262         */
00263         PLCORE_API void RemoveAttribute(const String &sName);
00264 
00265         /**
00266         *  @brief
00267         *    Access the first attribute in this element
00268         *
00269         *  @return
00270         *    The first attribute, a null pointer if there's no first attribute
00271         */
00272         inline XmlAttribute *GetFirstAttribute();
00273         inline const XmlAttribute *GetFirstAttribute() const;
00274 
00275         /**
00276         *  @brief
00277         *    Access the last attribute in this element
00278         *
00279         *  @return
00280         *    The last attribute, a null pointer if there's no last attribute
00281         */
00282         inline XmlAttribute *GetLastAttribute();
00283         inline const XmlAttribute *GetLastAttribute() const;
00284 
00285         /**
00286         *  @brief
00287         *    Convenience function for easy access to the text inside an element
00288         *
00289         *  @remarks
00290         *    Although easy and concise, GetText() is limited compared to getting the
00291         *    XmlText child and accessing it directly.
00292         *
00293         *    If the first child of 'this' is a XmlText, the GetText()
00294         *    returns the character string of the text node, else null is returned.
00295         *
00296         *    This is a convenient method for getting the text of simple contained text:
00297         *    @verbatim
00298         *    <foo>This is text</foo>
00299         *    const char *pszText = fooElement->GetText();
00300         *    @endverbatim
00301         *
00302         *    'pszText' will be a pointer to "This is text".
00303         *
00304         *    Note that this function can be misleading. If the element foo was created from
00305         *    this XML:
00306         *    @verbatim
00307         *    <foo><b>This is text</b></foo>
00308         *    @endverbatim
00309         *
00310         *    then the value of str would be null. The first child node isn't a text node, it is
00311         *    another element. From this XML:
00312         *    @verbatim
00313         *    <foo>This is <b>text</b></foo>
00314         *    @endverbatim
00315         *    GetText() will return "This is ".
00316         *
00317         *    WARNING: GetText() accesses a child node - don't become confused with the
00318         *             similarly named XmlNode::ToText() which is safe type casts on the referenced node.
00319         *
00320         *  @return
00321         *    Text inside an element, or empty string
00322         */
00323         PLCORE_API String GetText() const;
00324 
00325 
00326     //[-------------------------------------------------------]
00327     //[ Public virtual XmlBase functions                      ]
00328     //[-------------------------------------------------------]
00329     public:
00330         PLCORE_API virtual bool Save(File &cFile, uint32 nDepth = 0) override;
00331         PLCORE_API virtual String ToString(uint32 nDepth = 0) const override;
00332         PLCORE_API virtual const char *Parse(const char *pszData, XmlParsingData *pData = nullptr, EEncoding nEncoding = EncodingUnknown) override;
00333 
00334 
00335     //[-------------------------------------------------------]
00336     //[ Public virtual XmlNode functions                      ]
00337     //[-------------------------------------------------------]
00338     public:
00339         PLCORE_API virtual XmlNode *Clone() const override;
00340 
00341 
00342     //[-------------------------------------------------------]
00343     //[ Private classes                                       ]
00344     //[-------------------------------------------------------]
00345     private:
00346         /**
00347         *  @brief
00348         *    A internal class used to manage a group of attributes
00349         */
00350         class XmlAttributeSet {
00351         public:
00352             XmlAttributeSet();
00353             ~XmlAttributeSet();
00354 
00355             void Add(XmlAttribute &cAttribute);
00356             void Remove(XmlAttribute &cAttribute);
00357 
00358             const XmlAttribute *GetFirst()  const   { return ( cSentinel.m_pNextAttribute     == &cSentinel ) ? 0 : cSentinel.m_pNextAttribute; }
00359             XmlAttribute *GetFirst()                { return ( cSentinel.m_pNextAttribute     == &cSentinel ) ? 0 : cSentinel.m_pNextAttribute; }
00360             const XmlAttribute *GetLast() const     { return ( cSentinel.m_pPreviousAttribute == &cSentinel ) ? 0 : cSentinel.m_pPreviousAttribute; }
00361             XmlAttribute *GetLast()                 { return ( cSentinel.m_pPreviousAttribute == &cSentinel ) ? 0 : cSentinel.m_pPreviousAttribute; }
00362 
00363             XmlAttribute *Find(const String &sName) const;
00364             XmlAttribute *FindOrCreate(const String &sName);
00365 
00366         private:
00367             XmlAttributeSet(const XmlAttributeSet &cSource) { /** Not implemented */ };
00368             void operator =(const XmlAttributeSet &cSource) { /** Not implemented */ };
00369 
00370             XmlAttribute cSentinel;
00371         };
00372 
00373 
00374     //[-------------------------------------------------------]
00375     //[ Private functions                                     ]
00376     //[-------------------------------------------------------]
00377     private:
00378         /**
00379         *  @brief
00380         *    Like clear, but initializes 'this' object as well
00381         */
00382         void ClearThis();
00383 
00384         /**
00385         *  @brief
00386         *    Reads the "value" of the element -- another element, or text
00387         *
00388         *  @param[in] pszData
00389         *    Parsing data, if a null pointer, an error will be returned
00390         *  @param[in] pData
00391         *    Parsing data, can be a null pointer
00392         *  @param[in] nEncoding
00393         *    Encoding
00394         *
00395         *  @return
00396         *    Read value
00397         *
00398         *  @note
00399         *    - This should terminate with the current end tag
00400         */
00401         const char *ReadValue(const char *pszData, XmlParsingData *pData, EEncoding nEncoding);
00402 
00403 
00404     //[-------------------------------------------------------]
00405     //[ Private data                                          ]
00406     //[-------------------------------------------------------]
00407     private:
00408         XmlAttributeSet m_cAttributeSet;    /**< Attribute set */
00409 
00410 
00411 };
00412 
00413 
00414 //[-------------------------------------------------------]
00415 //[ Namespace                                             ]
00416 //[-------------------------------------------------------]
00417 } // PLCore
00418 
00419 
00420 //[-------------------------------------------------------]
00421 //[ Implementation                                        ]
00422 //[-------------------------------------------------------]
00423 #include "PLCore/Xml/XmlElement.inl"
00424 
00425 
00426 #endif // __PLCORE_XML_ELEMENT_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