PixelLightAPI
.
|
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__
|