libcrn  3.9.5
A document image processing library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CRNXml.h
Go to the documentation of this file.
1 /* Copyright 2012-2014 CoReNum
2  *
3  * This file is part of libcrn.
4  *
5  * libcrn is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * libcrn is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with libcrn. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * file: CRNXml.h
19  * \author Yann LEYDIER
20  */
21 
22 #ifndef CRNXml_HEADER
23 #define CRNXml_HEADER
24 
25 #include <CRNIO/CRNPath.h>
27 
28 namespace tinyxml2
29 {
30  class XMLDocument;
31  class XMLNode;
32  class XMLComment;
33  class XMLElement;
34  class XMLText;
35  class XMLAttribute;
36 }
37 namespace crn
38 {
47  namespace xml
48  {
49  class Element;
50  class Comment;
51  class Text;
60  class Node
61  {
62  public:
64  virtual ~Node() {}
65  Node(const Node&) = default;
66  Node(Node&&) = default;
67  Node& operator=(const Node&) = default;
68  Node& operator=(Node&&) = default;
69 
71  bool IsElement();
73  bool IsComment();
75  bool IsText();
76 
82  Text AsText();
83 
85  operator bool() const noexcept { return node != nullptr; }
87  bool operator!() const noexcept { return node == nullptr; }
89  bool operator==(const Node &other) const noexcept { return node == other.node; }
91  bool operator!=(const Node &other) const noexcept { return !(*this == other); }
92 
94  virtual StringUTF8 GetValue() const;
96  void SetValue(const StringUTF8 &s);
97 
99  Node GetParent();
100 
106  Node& operator++();
108  Node operator++(int);
109 
111  Element GetNextSiblingElement(const StringUTF8 &name = "");
113  Element GetPreviousSiblingElement(const StringUTF8 &name = "");
114 
115  protected:
117  Node(tinyxml2::XMLNode *n, const SCharsetConverter &c);
118  SCharsetConverter conv;
119 
120  private:
121  tinyxml2::XMLNode *node;
122 
123  friend class Document;
124  friend class Element;
125  };
126 
135  class Element: public Node
136  {
137  public:
139  virtual ~Element() override {}
140  Element(const Element&) = default;
141  Element(Element&&) = default;
142  Element& operator=(const Element&) = default;
143  Element& operator=(Element&&) = default;
144 
146  StringUTF8 GetName() const { return GetValue(); }
148  void SetName(const StringUTF8 &s) { SetValue(s); }
149 
151  Element& operator++();
153  Element operator++(int);
154 
155  // Children
157  size_t GetNbSubnodes() const { return nb_subnodes; }
159  size_t GetNbSubelements() const { return nb_subelems; }
163  Node GetLastChild();
165  Node BeginNode() { return GetFirstChild(); }
167  Node EndNode() { return Node(nullptr, conv); }
168 
170  Element GetFirstChildElement(const StringUTF8 &name = "");
172  Element GetLastChildElement(const StringUTF8 &name = "");
176  Element EndElement() { return Element(nullptr, conv); }
177 
180 
182  Element PushBackElement(const StringUTF8 &name);
184  Element PushFrontElement(const StringUTF8 &name);
186  Element InsertElement(Node &n, const StringUTF8 &name);
187 
189  Comment PushBackComment(const StringUTF8 &text);
191  Comment PushFrontComment(const StringUTF8 &text);
193  Comment InsertComment(Node &n, const StringUTF8 &text);
194 
196  Text PushBackText(const StringUTF8 &text, bool cdata = false);
198  Text PushFrontText(const StringUTF8 &text, bool cdata = false);
200  Text InsertText(Node &n, const StringUTF8 &text, bool cdata = false);
201 
203  Node PushBackClone(Node &n, bool recursive = false);
204 
206  void Clear();
208  void RemoveChild(Node &n);
209 
210  // Attributes
219  template<typename T> T GetAttribute(const StringUTF8 &name, bool silent = true) const
220  {
221  T attr;
222  if (silent)
223  {
224  try { queryAttribute(name, attr); }
225  catch (...) { return T(0); }
226  }
227  else
228  queryAttribute(name, attr);
229  return attr;
230  }
232  void SetAttribute(const StringUTF8 &name, const StringUTF8 &value);
234  void RemoveAttribute(const StringUTF8 &name);
235 
236  class Attribute
237  {
238  public:
239  Attribute(const Attribute&) = default;
240  Attribute(Attribute&&) = default;
241  Attribute& operator=(const Attribute&) = default;
242  Attribute& operator=(Attribute&&) = default;
245 
249  Attribute operator++(int);
251  Attribute Next();
252 
254  bool operator==(const Attribute &other) const noexcept { return attr == other.attr; }
256  bool operator!=(const Attribute &other) const noexcept { return !(*this == other); }
257 
259  StringUTF8 GetName() const;
267  template<typename T> T GetValue(bool silent = true) const
268  {
269  T val;
270  if (silent)
271  {
272  try { queryValue(val); }
273  catch (...) { return T(0); }
274  }
275  else
276  queryValue(val);
277  return val;
278  }
280  void SetValue(const StringUTF8 &value);
281 
282  private:
284  Attribute(tinyxml2::XMLAttribute *a, const SCharsetConverter &c);
285 
287  void queryValue(StringUTF8 &value) const;
289  void queryValue(int &value) const;
291  void queryValue(unsigned int &value) const;
293  void queryValue(bool &value) const;
295  void queryValue(double &value) const;
297  void queryValue(float &value) const;
298 
300  SCharsetConverter conv;
301 
302  friend class Element;
303  };
308 
309  protected:
311  Element(tinyxml2::XMLElement *el, const SCharsetConverter &c);
312 
313  private:
315  void queryAttribute(const StringUTF8 &name, StringUTF8 &value) const;
317  void queryAttribute(const StringUTF8 &name, int &value) const;
319  void queryAttribute(const StringUTF8 &name, unsigned int &value) const;
321  void queryAttribute(const StringUTF8 &name, bool &value) const;
323  void queryAttribute(const StringUTF8 &name, double &value) const;
325  void queryAttribute(const StringUTF8 &name, float &value) const;
327  void count_subnondes();
328 
329  tinyxml2::XMLElement *element;
330  size_t nb_subnodes, nb_subelems;
331 
332  friend class Node;
333  friend class Document;
334  };
343  template<> inline StringUTF8 Element::GetAttribute<StringUTF8>(const StringUTF8 &name, bool silent) const
344  {
345  StringUTF8 attr;
346  if (silent)
347  {
348  try { queryAttribute(name, attr); }
349  catch (...) { return StringUTF8(); }
350  }
351  else
352  queryAttribute(name, attr);
353  return attr;
354  }
355 
364  class Comment: public Node
365  {
366  public:
367  Comment(const Comment&) = default;
368  Comment(Comment&&) = default;
369  Comment& operator=(const Comment&) = default;
370  Comment& operator=(Comment&&) = default;
372  virtual ~Comment() override {}
373 
374  protected:
376  Comment(tinyxml2::XMLComment *c, const SCharsetConverter &co);
377 
378  private:
379  tinyxml2::XMLComment *comment;
380 
381  friend class Element;
382  friend class Node;
383  friend class Document;
384  };
385 
394  class Text: public Node
395  {
396  public:
397  Text(const Text&) = default;
398  Text(Text&&) = default;
399  Text& operator=(const Text&) = default;
400  Text& operator=(Text&&) = default;
402  virtual ~Text() override {}
403 
405  bool IsCData() const;
406 
408  virtual StringUTF8 GetValue() const override;
409  protected:
411  Text(tinyxml2::XMLText *t, const SCharsetConverter &c);
412 
413  private:
414  tinyxml2::XMLText *text;
415 
416  friend class Element;
417  friend class Node;
418  friend class Document;
419  };
420 
429  class Document
430  {
431  public:
433  Document(const StringUTF8 &encoding = "UTF-8", const StringUTF8 &version = "1.0", bool char_conversion_throws = true);
435  Document(const Path &fname, bool char_conversion_throws = true);
437  Document(const char *content, bool char_conversion_throws = true);
438  Document(const Document&) = delete;
439  Document(Document&&);
440  Document& operator=(const Document&) = delete;
443  virtual ~Document();
444 
446  operator bool() const noexcept { return doc != nullptr; }
448  bool operator!() const noexcept { return doc == nullptr; }
449 
451  void Save(const Path &fname);
453  void Save();
455  const Path& GetFilename() const noexcept { return filename; }
456 
458  const StringUTF8& GetEncoding() const noexcept { return enc; }
460  const StringUTF8& GetVersion() const noexcept { return ver; }
461 
463  Element GetRoot();
464 
466  Node GetFirstNode();
468  Node GetLastNode();
470  Node BeginNode() { return GetFirstNode(); }
472  Node EndNode() { return Node(nullptr, conv); }
473 
475  Element GetFirstElement(const StringUTF8 &name = "");
477  Element GetLastElement(const StringUTF8 &name = "");
481  Element EndElement() { return Element(nullptr, conv); }
482 
484  Element PushBackElement(const StringUTF8 &name);
486  Element InsertElement(Node &n, const StringUTF8 &name);
487 
489  Comment PushBackComment(const StringUTF8 &text);
491  Comment InsertComment(Node &n, const StringUTF8 &text);
492 
494  Node PushBackClone(Node &n, bool recursive = false);
495 
498 
499  private:
500  std::unique_ptr<tinyxml2::XMLDocument> doc;
501  StringUTF8 enc, ver;
502  SCharsetConverter conv;
503  Path filename;
504  };
505 
506  }
507 }
508 
509 
510 #endif
511 
512 
Attribute & operator++()
Move to next attribute.
Definition: CRNXml.cpp:750
void Save()
Saves to file.
Definition: CRNXml.cpp:1022
bool IsText()
Checks if the node is a text.
Definition: CRNXml.cpp:119
virtual StringUTF8 GetValue() const override
Gets the content of the node.
Definition: CRNXml.cpp:888
Comment PushFrontComment(const StringUTF8 &text)
Adds a comment at the front of the children list.
Definition: CRNXml.cpp:430
Node PushBackClone(Node &n, bool recursive=false)
Adds a copy of a node at the end of the children list.
Definition: CRNXml.cpp:523
size_t GetNbSubelements() const
Returns the number of sub-elements.
Definition: CRNXml.h:159
void Clear()
Removes all children.
Definition: CRNXml.cpp:572
Text(const Text &)=default
Text & operator=(const Text &)=default
Comment PushBackComment(const StringUTF8 &text)
Adds a comment at the end of the children list.
Definition: CRNXml.cpp:1126
void SetName(const StringUTF8 &s)
Sets the label of the element.
Definition: CRNXml.h:148
XML comment.
Definition: CRNXml.h:364
XML element.
Definition: CRNXml.h:135
bool operator!() const noexcept
Checks if the document is not open.
Definition: CRNXml.h:448
StringUTF8 GetName() const
Gets the label of the element.
Definition: CRNXml.h:146
SCharsetConverter conv
Definition: CRNXml.h:118
bool IsComment()
Checks if the node is a comment.
Definition: CRNXml.cpp:111
Comment & operator=(const Comment &)=default
Element EndElement()
Gets a null node.
Definition: CRNXml.h:481
Node EndNode()
Gets a null node.
Definition: CRNXml.h:167
Element(const Element &)=default
Text AsText()
Converts to text.
Definition: CRNXml.cpp:158
XML document.
Definition: CRNXml.h:429
Element GetRoot()
Gets the first element.
Definition: CRNXml.cpp:1034
~Attribute()
Destructor.
Definition: CRNXml.h:244
Element & operator=(const Element &)=default
Element PushBackElement(const StringUTF8 &name)
Adds an element at the end of the children list.
Definition: CRNXml.cpp:1087
Element AsElement()
Converts to element.
Definition: CRNXml.cpp:130
Attribute EndAttribute()
Gets the null attribute.
Definition: CRNXml.cpp:626
Element InsertElement(Node &n, const StringUTF8 &name)
Inserts an element after a node.
Definition: CRNXml.cpp:393
Element GetLastElement(const StringUTF8 &name="")
Gets the last child element.
Definition: CRNXml.cpp:1075
Element GetNextSiblingElement(const StringUTF8 &name="")
Gets the next sibling element.
Definition: CRNXml.cpp:247
Element BeginElement()
Gets the first child element.
Definition: CRNXml.h:174
bool operator!() const noexcept
Checks if the node is null.
Definition: CRNXml.h:87
Attribute & operator=(const Attribute &)=default
Text PushBackText(const StringUTF8 &text, bool cdata=false)
Adds a text at the end of the children list.
Definition: CRNXml.cpp:467
Element GetLastChildElement(const StringUTF8 &name="")
Gets the last child element.
Definition: CRNXml.cpp:329
Text PushFrontText(const StringUTF8 &text, bool cdata=false)
Adds a text at the front of the children list.
Definition: CRNXml.cpp:483
Node GetLastNode()
Gets the last child node.
Definition: CRNXml.cpp:1053
Comment(const Comment &)=default
size_t GetNbSubnodes() const
Returns the number of sub-nodes.
Definition: CRNXml.h:157
Node GetParent()
Gets the parent node if any.
Definition: CRNXml.cpp:189
Comment InsertComment(Node &n, const StringUTF8 &text)
Inserts a comment after a node.
Definition: CRNXml.cpp:1141
virtual ~Element() override
Destructor.
Definition: CRNXml.h:139
const StringUTF8 & GetEncoding() const noexcept
Gets the character encoding of the file.
Definition: CRNXml.h:458
const StringUTF8 & GetVersion() const noexcept
Gets the XML version of the file.
Definition: CRNXml.h:460
Document & operator=(const Document &)=delete
Element GetFirstChildElement(const StringUTF8 &name="")
Gets the first child element.
Definition: CRNXml.cpp:320
Node GetLastChild()
Gets the last child node.
Definition: CRNXml.cpp:311
A convenience class for file paths.
Definition: CRNPath.h:39
bool IsElement()
Checks if the node is an element.
Definition: CRNXml.cpp:103
XML text.
Definition: CRNXml.h:394
virtual StringUTF8 GetValue() const
Gets the content of the node.
Definition: CRNXml.cpp:171
Element GetPreviousSiblingElement(const StringUTF8 &name="")
Gets the previous sibling element.
Definition: CRNXml.cpp:236
Node GetFirstNode()
Gets the first child node.
Definition: CRNXml.cpp:1045
void SetValue(const StringUTF8 &s)
Sets the content of the node.
Definition: CRNXml.cpp:181
Element BeginElement()
Gets the first child element.
Definition: CRNXml.h:479
Document(const StringUTF8 &encoding="UTF-8", const StringUTF8 &version="1.0", bool char_conversion_throws=true)
Constructor.
void SetAttribute(const StringUTF8 &name, const StringUTF8 &value)
Sets the value of an attribute.
Definition: CRNXml.cpp:595
StringUTF8 AsString()
Exports the document to a string.
Definition: CRNXml.cpp:1218
Element & operator++()
Moves to the next sibling element.
Definition: CRNXml.cpp:284
void SetValue(const StringUTF8 &value)
Sets the value of the attribute.
Definition: CRNXml.cpp:787
StringUTF8 GetName() const
Gets the name of the attribute.
Definition: CRNXml.cpp:777
T GetAttribute(const StringUTF8 &name, bool silent=true) const
Gets an attribute.
Definition: CRNXml.h:219
Node EndNode()
Gets a null node.
Definition: CRNXml.h:472
Node GetFirstChild()
Gets the first child node.
Definition: CRNXml.cpp:303
Element GetFirstElement(const StringUTF8 &name="")
Gets the first child element.
Definition: CRNXml.cpp:1064
bool operator!=(const Attribute &other) const noexcept
Comparison operator.
Definition: CRNXml.h:256
Comment PushBackComment(const StringUTF8 &text)
Adds a comment at the end of the children list.
Definition: CRNXml.cpp:416
Node BeginNode()
Gets the first child node.
Definition: CRNXml.h:165
Attribute Next()
Gets next attribute.
Definition: CRNXml.cpp:769
Text InsertText(Node &n, const StringUTF8 &text, bool cdata=false)
Inserts a text after a node.
Definition: CRNXml.cpp:502
virtual ~Node()
Destructor.
Definition: CRNXml.h:64
Node & operator++()
Moves to the next sibling node.
Definition: CRNXml.cpp:214
Node GetPreviousSibling()
Gets the previous sibling node.
Definition: CRNXml.cpp:198
virtual ~Text() override
Destructor.
Definition: CRNXml.h:402
Node GetNextSibling()
Gets the next sibling node.
Definition: CRNXml.cpp:206
virtual ~Comment() override
Destructor.
Definition: CRNXml.h:372
Attribute BeginAttribute()
Gets the first attribute.
Definition: CRNXml.cpp:618
StringUTF8 GetFirstChildText()
Gets the first child as text.
Definition: CRNXml.cpp:339
Element InsertElement(Node &n, const StringUTF8 &name)
Inserts an element after a node.
Definition: CRNXml.cpp:1105
Node & operator=(const Node &)=default
Element PushFrontElement(const StringUTF8 &name)
Adds an element at the front of the children list.
Definition: CRNXml.cpp:373
Comment AsComment()
Converts to comment.
Definition: CRNXml.cpp:144
A character string class.
Definition: CRNStringUTF8.h:49
Node PushBackClone(Node &n, bool recursive=false)
Adds a copy of a node at the end of the children list.
Definition: CRNXml.cpp:1160
Node(const Node &)=default
bool IsCData() const
Is the text a CData?
Definition: CRNXml.cpp:880
const Path & GetFilename() const noexcept
Gets the filename if the document exists on the disk.
Definition: CRNXml.h:455
virtual ~Document()
Destructor.
friend class Node
Definition: CRNXml.h:332
bool operator==(const Attribute &other) const noexcept
Comparison operator.
Definition: CRNXml.h:254
Element PushBackElement(const StringUTF8 &name)
Adds an element at the end of the children list.
Definition: CRNXml.cpp:355
void RemoveChild(Node &n)
Removes a child node.
Definition: CRNXml.cpp:581
Comment InsertComment(Node &n, const StringUTF8 &text)
Inserts a comment after a node.
Definition: CRNXml.cpp:446
bool operator!=(const Node &other) const noexcept
Comparison operator.
Definition: CRNXml.h:91
T GetValue(bool silent=true) const
Gets the value of the attribute.
Definition: CRNXml.h:267
Element EndElement()
Gets a null node.
Definition: CRNXml.h:176
XML node.
Definition: CRNXml.h:60
Node BeginNode()
Gets the first child node.
Definition: CRNXml.h:470
Attribute(const Attribute &)=default
bool operator==(const Node &other) const noexcept
Comparison operator.
Definition: CRNXml.h:89
void RemoveAttribute(const StringUTF8 &name)
Removes an attribute.
Definition: CRNXml.cpp:608