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