PageRenderTime 24ms CodeModel.GetById 37ms RepoModel.GetById 0ms app.codeStats 0ms

/include/AXmlElement.hpp

http://aobjectserver.codeplex.com
C++ Header | 723 lines | 125 code | 91 blank | 507 comment | 0 complexity | 495187e062f1bb7f49546bf96ae7b3c5 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /*
  2. Written by Alex Chachanashvili
  3. $Id: AXmlElement.hpp 281 2009-01-15 22:10:52Z achacha $
  4. */
  5. #ifndef INCLUDED__AXmlElement_HPP__
  6. #define INCLUDED__AXmlElement_HPP__
  7. #include "apiABase.hpp"
  8. #include "ADebugDumpable.hpp"
  9. #include "AXmlAttributes.hpp"
  10. #include "AXmlEmittable.hpp"
  11. #include "AJsonEmittable.hpp"
  12. /*!
  13. Base class that represents an XML element node
  14. The path parameter is NOT xpath, just a simple version to access the element or attribute
  15. All searching assumes (if this is /root and has child0 and child1):
  16. absolute path must include this element (/root/child1)
  17. relative path starts with contained elements and omits this element (child1)
  18. All content added as pointer is owned and deleted by this element
  19. Items added by reference are either cloned or emitted to data
  20. */
  21. class ABASE_API AXmlElement : public ADebugDumpable, public AXmlEmittable, public AJsonEmittable
  22. {
  23. public:
  24. //! The way the data will be encoded
  25. enum Encoding
  26. {
  27. ENC_NONE = 0, //!< Text as is
  28. ENC_URL, //!< Url encoded text
  29. ENC_CDATASAFE, //!< <![CDATA[ data ]]> with data made safe for CData
  30. ENC_CDATADIRECT, //!< <![CDATA[ data ]]> with data as is
  31. ENC_XMLSAFE, //!< Replaces < > & with &lt; &gt; &amp;
  32. ENC_BASE64, //!< Encodes with Base64
  33. ENC_CDATAHEXDUMP //!< Debugging format useful for examining binary data
  34. };
  35. public:
  36. //! Node container
  37. typedef std::list<AXmlElement *> CONTAINER;
  38. //! Constant node container
  39. typedef std::list<const AXmlElement *> CONST_CONTAINER;
  40. /*!
  41. Default ctor
  42. @param pParent to attach this element to
  43. */
  44. AXmlElement(AXmlElement *pParent = NULL);
  45. /*!
  46. ctor with name
  47. @param name to assign to this element
  48. @param pParent to attach this element to
  49. */
  50. AXmlElement(const AString& name, AXmlElement *pParent = NULL);
  51. /*!
  52. ctor with element name and attributes
  53. @param name to assign to this element
  54. @param attrs to attaching to this element
  55. @param pParent to attach this element to
  56. */
  57. AXmlElement(const AString& name, const AXmlAttributes& attrs, AXmlElement *pParent = NULL);
  58. /*!
  59. Copy ctor will clone content recursively
  60. @param that other element
  61. @param pParent to attach this element to
  62. */
  63. AXmlElement(const AXmlElement& that, AXmlElement *pParent = NULL);
  64. //! dtor
  65. virtual ~AXmlElement();
  66. /*!
  67. Get attributes
  68. @return constant reference to the attributes object
  69. */
  70. const AXmlAttributes& getAttributes() const;
  71. /*!
  72. Use attributes
  73. @return reference to the attributes object
  74. */
  75. AXmlAttributes& useAttributes();
  76. /*!
  77. Check if a name equals this element and attribute exists
  78. Format: name@attr
  79. e.g.
  80. Given: <a foo='1'>something</a>
  81. a@foo exists
  82. a exists
  83. @foo exists
  84. b does not
  85. @param nameattr of this element+attribute
  86. @return true if name matches and attribute exists
  87. */
  88. bool isNameEquals(const AString& nameattr) const;
  89. /*!
  90. Get name of this element
  91. If comparing to name@attribute, use isNameEquals
  92. @return constant reference to the element name
  93. @see isNameEquals
  94. */
  95. const AString& getName() const;
  96. /*!
  97. Use name of this element
  98. If comparing to name@attribute, use isNameEquals
  99. @return reference to the element name
  100. @see isNameEquals
  101. */
  102. AString& useName();
  103. /*!
  104. Returns true if exists
  105. @param path to check
  106. @return true if element at path is found
  107. */
  108. bool exists(const AString& path) const;
  109. /*!
  110. Removes element and all children
  111. @param path to lookup
  112. @return true if found and removed
  113. */
  114. bool remove(const AString& path);
  115. /*!
  116. Checks if this element contains child elements
  117. @return true if this element contains other elements
  118. */
  119. bool hasElements() const;
  120. /*!
  121. Checks if an element type
  122. @return true if this is an AXmlElement type
  123. */
  124. virtual bool isElement() const;
  125. /*!
  126. Checks if data type
  127. @return true if this is an AXmlData type
  128. @see AXmlData
  129. */
  130. virtual bool isData() const;
  131. /*!
  132. Checks if instruction
  133. @return true if this is an AXmlInstruction type
  134. @see AXmlInstruction
  135. */
  136. virtual bool isInstruction() const;
  137. /*!
  138. Emitted data corresponding to the path
  139. @param path to look up
  140. @param target to append to
  141. @return true if exists
  142. */
  143. bool emitString(const AString& path, AOutputBuffer& target) const;
  144. /*!
  145. AString of content at the path
  146. This is not the most efficient call due to temporary return object, but useful for initializing statics
  147. @param path to look up
  148. @param strDefault to use if path does not refer to an existing element
  149. @return emitted data into a string for a path or default
  150. */
  151. AString getString(const AString& path, const AString& strDefault) const;
  152. /*!
  153. int at from content at the path
  154. @param path to look up
  155. @param iDefault default value if path does not refer to an existing element
  156. @return result that is converted to int if does not exist default is returned
  157. */
  158. int getInt(const AString& path, int iDefault) const;
  159. /*!
  160. size_t from content at the path
  161. @param path to look up
  162. @param iDefault default value if path does not refer to an existing element
  163. @return result that is converted to size_t if does not exist default is returned
  164. */
  165. size_t getSize_t(const AString& path, size_t iDefault) const;
  166. /*!
  167. u4 from content at the path
  168. @param path to look up
  169. @param iDefault default value if path does not refer to an existing element
  170. @return result that is converted to u4 if does not exist default is returned
  171. */
  172. u4 getU4(const AString& path, u4 iDefault) const;
  173. /*!
  174. u8 from content at the path
  175. @param path to look up
  176. @param iDefault default value if path does not refer to an existing element
  177. @return result that is converted to u8 if does not exist default is returned
  178. */
  179. u8 getU8(const AString& path, u8 iDefault) const;
  180. /*!
  181. bool from content at the path
  182. @param path to look up
  183. @param boolDefault default value if path does not refer to an existing element
  184. @return result that is converted to bool if does not exist default is returned
  185. */
  186. bool getBool(const AString& path, bool boolDefault) const;
  187. /*!
  188. Saves value into DOM at path, overwrites existing
  189. @param path to look up
  190. @param value to set
  191. @param encoding to use
  192. */
  193. void setString(const AString& path, const AString& value, AXmlElement::Encoding encoding = AXmlElement::ENC_NONE);
  194. /*!
  195. Saves value into DOM at path, overwrites existing
  196. @param path to look up
  197. @param value to set
  198. */
  199. void setInt(const AString& path, int value);
  200. /*!
  201. Saves value into DOM at path, overwrites existing
  202. @param path to look up
  203. @param value to set
  204. */
  205. void setSize_t(const AString& path, size_t value);
  206. /*!
  207. Saves value into DOM at path, overwrites existing
  208. Converts bool to AString
  209. @param path to look up
  210. @param value to set
  211. */
  212. void setBool(const AString& path, bool value);
  213. /*!
  214. Find path based on this element as root
  215. If element name contains @attrib, it checks if attribute named exists on the element
  216. @param path to look up
  217. @return reference to the AXmlElement or NULL if not found
  218. */
  219. AXmlElement *findElement(const AString& path);
  220. /*!
  221. Find path based on this element as root
  222. If element name contains @attrib, it checks if attribute named exists on the element
  223. @param path to look up
  224. @return constant reference to the AXmlElement or NULL if not found
  225. */
  226. const AXmlElement *findElement(const AString& path) const;
  227. /*!
  228. Searching for path (ignores anything after @)
  229. If this element is 'a' and contains "b/bb,c/cc@foo",d/dd
  230. The "/a/c/cc@foo" will be found. Current element must be first element of the path if absolute
  231. If path is relative then c/cc will find 2nd child cc in child c
  232. Adds const AXmlElement* to the result container, will not clear the result, will append
  233. If element name contains @attrib, it checks if attribute named exists on the element
  234. @param path to look up
  235. @param result to append 'const AXmlElement' references to
  236. @return number of elements found
  237. */
  238. size_t find(const AString& path, CONST_CONTAINER& result) const;
  239. /*!
  240. Create a new element
  241. NOTE: the reference returned is to the NEWLY ADDED element and not the current element as with other non-add methods
  242. @param path to create/add
  243. @param insertIntoFront makes new element the first one if true, and appends to content end if false
  244. @return the newly added element
  245. */
  246. AXmlElement& addElement(const AString& path, bool insertIntoFront = false);
  247. /*!
  248. Overwrite an element or create new one if it does not exist
  249. Will find the first one
  250. NOTE: If path is found the reference returned is to the overwritten element and not the current element as with other non-add methods
  251. NOTE: If path not found the reference returned is to the NEWLY ADDED element and not the current element as with other non-add methods
  252. @param path to create/overwrite
  253. @return the overwritten/added element
  254. */
  255. AXmlElement& overwriteElement(const AString& path);
  256. /*!
  257. Adds a new element
  258. NOTE: If path is found the reference returned is to the overwritten element and not the current element as with other non-add methods
  259. NOTE: If path not found the reference returned is to the NEWLY ADDED element and not the current element as with other non-add methods
  260. @param path to look up
  261. @param object to add as a string (emit will be called on it)
  262. @param encoding to use on added string
  263. @param overwrite - will try to find existing structure to replace, otherwise will create new path
  264. @return the newly added element
  265. */
  266. AXmlElement& addElement(const AString& path, const AEmittable& object, AXmlElement::Encoding encoding = AXmlElement::ENC_NONE, bool overwrite = false, bool insertIntoFront = false);
  267. /*!
  268. Add AEmittable type (encoded as needed)
  269. @param object to emit to content data of this element
  270. @param encoding to use
  271. @return this object
  272. */
  273. AXmlElement& addData(const AEmittable& object, AXmlElement::Encoding encoding = AXmlElement::ENC_NONE);
  274. /*!
  275. Add const char * value to text/data of element
  276. @param value string to add to content data of this element
  277. @param length of the value to add
  278. @param encoding to use
  279. @return this object
  280. */
  281. AXmlElement& addData(const char *value, size_t length = AConstant::npos, AXmlElement::Encoding encoding = AXmlElement::ENC_NONE);
  282. /*!
  283. Add signed int value to text/data of element (no encoding)
  284. @param value (int as string) to add to content data of this element
  285. @return this object
  286. */
  287. AXmlElement& addData(const int value);
  288. /*!
  289. Add char value entered as is (no encoding)
  290. @param value char to add to content data of this element
  291. @return this object
  292. */
  293. AXmlElement& addData(const char value);
  294. /*!
  295. Add double value to text/data of element (no encoding)
  296. @param value (double as string) to add to content data of this element
  297. @return this object
  298. */
  299. AXmlElement& addData(const double value);
  300. /*!
  301. Add std::size_t value to text/data of element (no encoding)
  302. @param value (size_t as string) to add to content data of this element
  303. @return this object
  304. */
  305. AXmlElement& addData(const size_t value);
  306. /*!
  307. Set AEmittable type (encoded as needed)
  308. @param object to emit to set as content data of this element
  309. @param encoding to use
  310. @return this object
  311. */
  312. AXmlElement& setData(const AEmittable& object, AXmlElement::Encoding encoding = AXmlElement::ENC_NONE);
  313. /*!
  314. Set const char * value to text/data of element
  315. @param value string to set as content data of this element
  316. @param length of the value to set
  317. @param encoding to use
  318. @return this object
  319. */
  320. AXmlElement& setData(const char *value, size_t length = AConstant::npos, AXmlElement::Encoding encoding = AXmlElement::ENC_NONE);
  321. /*!
  322. Set signed int value to text/data of element (no encoding)
  323. @param value (int as string) to add to content data of this element
  324. @return this object
  325. */
  326. AXmlElement& setData(const int value);
  327. /*!
  328. Set char value entered as is (no encoding)
  329. @param value char to set to content data of this element
  330. @return this object
  331. */
  332. AXmlElement& setData(const char value);
  333. /*!
  334. Set double value to text/data of element (no encoding)
  335. @param value (double as string) to set to content data of this element
  336. @return this object
  337. */
  338. AXmlElement& setData(const double value);
  339. /*!
  340. Set std::size_t value to text/data of element (no encoding)
  341. @param value (size_t as string) to add to content data of this element
  342. @return this object
  343. */
  344. AXmlElement& setData(const size_t value);
  345. /*!
  346. Adds an XML/HTML comment
  347. @param comment to add
  348. @return this object
  349. */
  350. AXmlElement& addComment(const AString& comment);
  351. /*!
  352. Adds content element pointer
  353. this object will OWN the passed content pointer and release it when done
  354. If path is empty or "/", current element is used as base
  355. For valid path, elements will be added to this one to extend the path
  356. @param pContent to add to this element (will be OWNED by this element and deleted when done)
  357. @param path to add to
  358. @param insertIntoFront if true will replace first found, if false fill replace last found
  359. @return this object
  360. */
  361. AXmlElement& addContent(AXmlElement *pContent, const AString& path = AConstant::ASTRING_EMPTY, bool insertIntoFront = false);
  362. /*!
  363. AXmlEmittable added as content to the end of this element
  364. that.emitXml(*this) is called
  365. @param that other object to XML emit into current element
  366. @return this object
  367. */
  368. AXmlElement& addContent(const AXmlEmittable& that);
  369. /*!
  370. Add attribute (replaces any existing)
  371. @param attrs to add
  372. @return this object
  373. */
  374. AXmlElement& addAttributes(const AXmlAttributes& attrs);
  375. /*!
  376. Add attribute (replaces any existing)
  377. @param name of the attribute
  378. @param value of the attribute
  379. @return this object
  380. */
  381. AXmlElement& addAttribute(const AString& name, const AString& value = AConstant::ASTRING_EMPTY);
  382. /*!
  383. Add attribute (replaces any existing)
  384. @param name of the attribute
  385. @param value (converted to string) of the attribute
  386. @return this object
  387. */
  388. AXmlElement& addAttribute(const AString& name, const u4 value);
  389. /*!
  390. Add attribute (replaces any existing)
  391. @param name of the attribute
  392. @param value (converted to string) of the attribute
  393. @return this object
  394. */
  395. AXmlElement& addAttribute(const AString& name, const u8 value);
  396. /*!
  397. Add attribute (replaces any existing)
  398. @param name of the attribute
  399. @param value (converted to string) of the attribute
  400. @return this object
  401. */
  402. AXmlElement& addAttribute(const AString& name, const double value);
  403. /*!
  404. AEmittable
  405. @param target to append to
  406. */
  407. virtual void emit(AOutputBuffer& target) const;
  408. /*!
  409. AEmittable and other output methods
  410. @param target to append to
  411. @param indent >= 0 will make it human-readable by adding indent and CRLF
  412. */
  413. virtual void emit(AOutputBuffer& target, int indent) const;
  414. /*!
  415. AJsonEmittable
  416. @param target to emit to
  417. @param indent -1=none, >=0 for indent at each level, each recursive call increases indent internally
  418. */
  419. virtual void emitJson(AOutputBuffer& target, int indent = -1) const;
  420. /*!
  421. Emit content only, unecoded raw data
  422. @param target to emit to
  423. @return true if there was some content, false if no content or singular element
  424. */
  425. virtual bool emitContent(AOutputBuffer& target) const;
  426. /*!
  427. Emit Xml from path
  428. @param path to start emit at
  429. @param target to emit to
  430. @param indent -1=none, >=0 for indent at each level, each recursive call increases indent internally
  431. @return false if path not found
  432. */
  433. bool emitXmlFromPath(const AString& path, AOutputBuffer& target, int indent = -1) const;
  434. /*!
  435. Emit content from path
  436. @param path to start emit at
  437. @param target to emit to
  438. @return false if path not found
  439. */
  440. bool emitContentFromPath(const AString& path, AOutputBuffer& target) const;
  441. /*!
  442. AXmlEmittable
  443. Adds this element with all its content to thisRoot
  444. @param thisRoot to emit XML into
  445. @return thisRoot for convenience
  446. */
  447. virtual AXmlElement& emitXml(AXmlElement& thisRoot) const;
  448. /*!
  449. Emit XML content of this element into the given element (does not include the current element)
  450. @param rootThis to emit XML content into
  451. @return rootThis for convenience
  452. */
  453. virtual void emitXmlContent(AXmlElement& rootThis) const;
  454. /*!
  455. Emit the path of the current element based on absolute root
  456. Will traverse up parents until NULL parent is reached
  457. @param target to emit to
  458. */
  459. virtual void emitPath(AOutputBuffer& target) const;
  460. /*!
  461. Clear the content and attributes
  462. Detaches from parent
  463. NOTE: Does NOT clear the name of the object
  464. */
  465. virtual void clear();
  466. /*!
  467. Clears the content only
  468. */
  469. void clearContent();
  470. /*!
  471. Content
  472. List of AXmlElement objects contained in this one
  473. @return container of the content elements
  474. */
  475. const AXmlElement::CONTAINER& getContentContainer() const;
  476. /*!
  477. Get parent element
  478. @return parent element or NULL if none
  479. */
  480. AXmlElement *getParent() const { return mp_Parent; }
  481. /*!
  482. Set parent element
  483. @param pParent new parent element or NULL if none
  484. @return current parent element
  485. */
  486. AXmlElement *setParent(AXmlElement *pParent);
  487. /*!
  488. Clone of self used in deep copy
  489. @return new cloned object and copies of all the content/elements
  490. */
  491. virtual AXmlElement* clone() const;
  492. /*!
  493. Parsing XML from file
  494. NOTE: assumes actual XML element, not data or instruction
  495. Use AXmlDocument to parse entire XML documents
  496. @param aFile to read from
  497. */
  498. virtual void fromAFile(AFile& aFile);
  499. /*!
  500. Parsing XML to file
  501. NOTE: assumes actual XML element, not data or instruction
  502. Use AXmlDocument to parse entire XML documents
  503. @param aFile to read from
  504. */
  505. virtual void toAFile(AFile& aFile) const;
  506. protected:
  507. //! Element name
  508. AString m_Name;
  509. //! Content container
  510. CONTAINER m_Content;
  511. //! XML attributes
  512. AXmlAttributes m_Attributes;
  513. //! Parent element (NULL if none)
  514. AXmlElement *mp_Parent;
  515. //! Recursive search function
  516. AXmlElement *_get(LIST_AString& xparts) const;
  517. //! Indents with 2 spaces per indent
  518. inline void _indent(AOutputBuffer&, int) const;
  519. //! Find method for non const elements
  520. size_t _find(const AString& path, CONTAINER& result);
  521. //! Internal find
  522. size_t _const_find(LIST_AString listPath, AXmlElement::CONST_CONTAINER& result) const;
  523. //! Internal find
  524. size_t _nonconst_find(LIST_AString listPath, AXmlElement::CONTAINER& result);
  525. //! Add element
  526. AXmlElement *_addElement(const AString& path, bool overwrite, bool insertIntoFront = false);
  527. //! Remove child element
  528. void _removeChildElement(AXmlElement *);
  529. //! Add data to this element
  530. //! overwrite of true will clar existing content and replace it with value
  531. void _addData(const AEmittable& value, AXmlElement::Encoding encoding = AXmlElement::ENC_NONE, bool overwrite = false);
  532. //! Creates a new element
  533. AXmlElement *_createAndAppend(LIST_AString& xparts, AXmlElement* pParent, bool insertIntoFront = false);
  534. //! Attempts to overwrite if not found then creates
  535. AXmlElement *_getOrCreate(LIST_AString& xparts, AXmlElement* pParent, bool insertIntoFront = false);
  536. public:
  537. #ifdef __DEBUG_DUMP__
  538. virtual void debugDump(std::ostream& os = std::cerr, int indent = 0x0) const;
  539. #endif
  540. public:
  541. //a_For convenience and efficiency
  542. static const AString sstr_Start; //a_ "<"
  543. static const AString sstr_StartComment; //a_ "<!--"
  544. static const AString sstr_StartInstruction; //a_ "<?"
  545. static const AString sstr_StartEnd; //a_ "</"
  546. static const AString sstr_EndSingular; //a_ "/>"
  547. static const AString sstr_End; //a_ ">"
  548. static const AString sstr_EndOrWhitespace; //a_ "/> \t\n\r"
  549. static const AString sstr_EndInstruction; //a_ "?>"
  550. static const AString sstr_EndComment; //a_ "-->"
  551. static const AString sstr_EndInstructionOrWhitespace; //a_ "?> \t\n\r"
  552. };
  553. #endif // INCLUDED__AXmlElement_HPP__