XMLNode.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. /*
  2. * Author: Patrick-Christopher Mattulat
  3. * Company: Lynar Studios
  4. * E-Mail: webmaster@lynarstudios.com
  5. * Created: 2020-09-24
  6. * Changed: 2021-04-23
  7. *
  8. * */
  9. #include <ls_std/io/xml/XMLNode.hpp>
  10. #include <ls_std/utils/STLUtils.hpp>
  11. ls_std::XMLNode::XMLNode(std::string _name)
  12. : ls_std::Class("XMLNode"),
  13. name(std::move(_name))
  14. {}
  15. bool ls_std::XMLNode::addAttributeAfter(const std::shared_ptr<ls_std::XMLAttribute> &_attribute, const std::string &_name)
  16. {
  17. bool added{};
  18. auto iterator = this->attributes.begin();
  19. if (!this->_hasAttribute(_attribute->getName()))
  20. {
  21. while (iterator != this->attributes.end())
  22. {
  23. if ((*iterator)->getName() == _name)
  24. {
  25. iterator++;
  26. this->attributes.insert(iterator, _attribute);
  27. added = true;
  28. break;
  29. }
  30. iterator++;
  31. }
  32. }
  33. return added;
  34. }
  35. bool ls_std::XMLNode::addAttributeBefore(const std::shared_ptr<ls_std::XMLAttribute> &_attribute, const std::string &_name)
  36. {
  37. bool added{};
  38. auto iterator = this->attributes.begin();
  39. if (!this->_hasAttribute(_attribute->getName()))
  40. {
  41. while (iterator != this->attributes.end())
  42. {
  43. if ((*iterator)->getName() == _name)
  44. {
  45. this->attributes.insert(iterator, _attribute);
  46. added = true;
  47. break;
  48. }
  49. iterator++;
  50. }
  51. }
  52. return added;
  53. }
  54. bool ls_std::XMLNode::addAttributeToBeginning(const std::shared_ptr<ls_std::XMLAttribute> &_attribute)
  55. {
  56. bool added{};
  57. if (_attribute != nullptr && !_hasAttribute(_attribute->getName()))
  58. {
  59. this->attributes.push_front(_attribute);
  60. added = true;
  61. }
  62. return added;
  63. }
  64. bool ls_std::XMLNode::addAttributeToEnd(const std::shared_ptr<ls_std::XMLAttribute> &_attribute)
  65. {
  66. bool added{};
  67. if (_attribute != nullptr && !_hasAttribute(_attribute->getName()))
  68. {
  69. this->attributes.push_back(_attribute);
  70. added = true;
  71. }
  72. return added;
  73. }
  74. bool ls_std::XMLNode::addChildAfter(const std::shared_ptr<ls_std::XMLNode> &_child, const std::shared_ptr<ls_std::XMLNode> &_search)
  75. {
  76. bool added{};
  77. auto iterator = this->children.begin();
  78. if (_child != nullptr && !this->_hasChild(_child))
  79. {
  80. while (iterator != this->children.end())
  81. {
  82. if (*iterator == _search)
  83. {
  84. iterator++;
  85. this->children.insert(iterator, _child);
  86. added = true;
  87. break;
  88. }
  89. iterator++;
  90. }
  91. }
  92. return added;
  93. }
  94. bool ls_std::XMLNode::addChildBefore(const std::shared_ptr<ls_std::XMLNode> &_child, const std::shared_ptr<ls_std::XMLNode> &_search)
  95. {
  96. bool added{};
  97. auto iterator = this->children.begin();
  98. if (_child != nullptr && !this->_hasChild(_child))
  99. {
  100. while (iterator != this->children.end())
  101. {
  102. if (*iterator == _search)
  103. {
  104. this->children.insert(iterator, _child);
  105. added = true;
  106. break;
  107. }
  108. iterator++;
  109. }
  110. }
  111. return added;
  112. }
  113. bool ls_std::XMLNode::addChildToBeginning(const std::shared_ptr<ls_std::XMLNode> &_child)
  114. {
  115. bool added{};
  116. if (_child != nullptr && !this->_hasChild(_child))
  117. {
  118. this->children.push_front(_child);
  119. added = true;
  120. }
  121. return added;
  122. }
  123. bool ls_std::XMLNode::addChildToEnd(const std::shared_ptr<ls_std::XMLNode> &_child)
  124. {
  125. bool added{};
  126. if (_child != nullptr && !this->_hasChild(_child))
  127. {
  128. this->children.push_back(_child);
  129. added = true;
  130. }
  131. return added;
  132. }
  133. void ls_std::XMLNode::clearValue()
  134. {
  135. this->value.clear();
  136. }
  137. std::list<std::shared_ptr<ls_std::XMLAttribute>> ls_std::XMLNode::getAttributes()
  138. {
  139. return this->attributes;
  140. }
  141. std::list<std::shared_ptr<ls_std::XMLNode>> ls_std::XMLNode::getChildren()
  142. {
  143. return this->children;
  144. }
  145. std::list<std::shared_ptr<ls_std::XMLNode>> ls_std::XMLNode::getChildren(const std::string &_name)
  146. {
  147. std::list<std::shared_ptr<ls_std::XMLNode>> childrenWithName{};
  148. for (const auto &child : this->children)
  149. {
  150. if (child->getName() == _name)
  151. {
  152. childrenWithName.push_back(child);
  153. }
  154. }
  155. return childrenWithName;
  156. }
  157. std::string ls_std::XMLNode::getName()
  158. {
  159. return this->name;
  160. }
  161. std::string ls_std::XMLNode::getValue()
  162. {
  163. return this->value;
  164. }
  165. bool ls_std::XMLNode::hasAttribute(const std::string &_name)
  166. {
  167. return this->_hasAttribute(_name);
  168. }
  169. bool ls_std::XMLNode::hasChild(const std::string &_name)
  170. {
  171. return this->_hasChild(_name);
  172. }
  173. bool ls_std::XMLNode::hasChild(const std::shared_ptr<ls_std::XMLNode> &_child)
  174. {
  175. return this->_hasChild(_child);
  176. }
  177. void ls_std::XMLNode::removeFirstAttribute()
  178. {
  179. if (!this->attributes.empty())
  180. {
  181. this->attributes.pop_front();
  182. }
  183. }
  184. void ls_std::XMLNode::removeLastAttribute()
  185. {
  186. if (!this->attributes.empty())
  187. {
  188. this->attributes.pop_back();
  189. }
  190. }
  191. void ls_std::XMLNode::removeFirstChild()
  192. {
  193. if (!this->children.empty())
  194. {
  195. this->children.pop_front();
  196. }
  197. }
  198. void ls_std::XMLNode::removeLastChild()
  199. {
  200. if (!this->children.empty())
  201. {
  202. this->children.pop_back();
  203. }
  204. }
  205. void ls_std::XMLNode::setName(std::string _name)
  206. {
  207. this->name = std::move(_name);
  208. }
  209. void ls_std::XMLNode::setValue(std::string _value)
  210. {
  211. this->value = std::move(_value);
  212. }
  213. std::string ls_std::XMLNode::toXML()
  214. {
  215. return this->_toXML_(0);
  216. }
  217. std::string ls_std::XMLNode::_toXML_(uint8_t _tabSize)
  218. {
  219. std::string xmlStream{};
  220. xmlStream += ls_std::XMLNode::_getTab(_tabSize);
  221. xmlStream += this->_toXMLOpenTag();
  222. xmlStream += this->_toXMLAttributes();
  223. xmlStream += this->_toXMLOpenTagClose();
  224. xmlStream += this->_toXMLValue();
  225. xmlStream += this->_toXMLChildren(_tabSize + TAB_SIZE);
  226. xmlStream += this->value.empty() ? ls_std::XMLNode::_getTab(_tabSize) : "";
  227. xmlStream += this->_toXMLCloseTag() + "\n";
  228. return xmlStream;
  229. }
  230. std::string ls_std::XMLNode::_getTab(uint8_t _tabSize)
  231. {
  232. std::string tab{};
  233. for (uint8_t index = 0; index < _tabSize; index++)
  234. {
  235. tab += " ";
  236. }
  237. return tab;
  238. }
  239. bool ls_std::XMLNode::_hasAttribute(const std::string &_name)
  240. {
  241. bool exists{};
  242. for (const auto &attribute : this->attributes)
  243. {
  244. if (attribute->getName() == _name)
  245. {
  246. exists = true;
  247. break;
  248. }
  249. }
  250. return exists;
  251. }
  252. bool ls_std::XMLNode::_hasChild(const std::shared_ptr<ls_std::XMLNode> &_child)
  253. {
  254. return ls_std::STLUtils::contains(this->children, _child);
  255. }
  256. bool ls_std::XMLNode::_hasChild(const std::string &_name)
  257. {
  258. bool exists{};
  259. for (const auto &attribute : this->children)
  260. {
  261. if (attribute->getName() == _name)
  262. {
  263. exists = true;
  264. break;
  265. }
  266. }
  267. return exists;
  268. }
  269. std::string ls_std::XMLNode::_toXMLAttributes()
  270. {
  271. std::string stream{};
  272. for (const auto &_attribute : this->attributes)
  273. {
  274. stream += " " + _attribute->toXML();
  275. }
  276. return stream;
  277. }
  278. std::string ls_std::XMLNode::_toXMLChildren(uint8_t _tabSize)
  279. {
  280. std::string stream{};
  281. if (this->value.empty())
  282. {
  283. for (const auto &_child : this->children)
  284. {
  285. stream += _child->_toXML_(_tabSize);
  286. }
  287. }
  288. return stream;
  289. }
  290. std::string ls_std::XMLNode::_toXMLCloseTag()
  291. {
  292. std::string stream{};
  293. if (!this->children.empty() || !this->value.empty())
  294. {
  295. stream = "</" + this->name + ">";
  296. }
  297. return stream;
  298. }
  299. std::string ls_std::XMLNode::_toXMLOpenTag()
  300. {
  301. return "<" + this->name;
  302. }
  303. std::string ls_std::XMLNode::_toXMLOpenTagClose()
  304. {
  305. std::string stream{};
  306. if (this->children.empty() && this->value.empty())
  307. {
  308. stream = "/>";
  309. }
  310. else
  311. {
  312. stream = ">";
  313. }
  314. return stream;
  315. }
  316. std::string ls_std::XMLNode::_toXMLValue()
  317. {
  318. return this->value.empty() ? "\n" : this->value;
  319. }