GammaLib  1.7.0.dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GXml.hpp
Go to the documentation of this file.
1 /***************************************************************************
2  * GXml.hpp - XML class *
3  * ----------------------------------------------------------------------- *
4  * copyright (C) 2010-2018 by Juergen Knoedlseder *
5  * ----------------------------------------------------------------------- *
6  * *
7  * This program is free software: you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation, either version 3 of the License, or *
10  * (at your option) any later version. *
11  * *
12  * This program is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15  * GNU General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU General Public License *
18  * along with this program. If not, see <http://www.gnu.org/licenses/>. *
19  * *
20  ***************************************************************************/
21 /**
22  * @file GXml.hpp
23  * @brief XML class interface definition
24  * @author Juergen Knoedlseder
25  */
26 
27 #ifndef GXML_HPP
28 #define GXML_HPP
29 
30 /* __ Includes ___________________________________________________________ */
31 #include <string>
32 #include "GContainer.hpp"
33 #include "GUrl.hpp"
34 #include "GXmlNode.hpp"
35 #include "GXmlDocument.hpp"
36 #include "GXmlElement.hpp"
37 #include "GXmlText.hpp"
38 
39 /* __ Forward declarations _______________________________________________ */
40 class GFilename;
41 
42 
43 /***********************************************************************//**
44  * @class GXml
45  *
46  * @brief XML class
47  *
48  * This class holds the content of an Extensible Markup Language (XML)
49  * document. An XML document is composed of a list of nodes, each of which
50  * may contain lists of nodes, which again can contain list of nodes and so
51  * on. This produces a tree made of nodes with an arbitrary complexity.
52  * Nodes that do not contain any further nodes are the endpoints of the tree
53  * that are called leafs.
54  *
55  * An example of an XML document is shown below
56  *
57  * <?xml version="1.0" encoding="UTF-8" ?>
58  * <element type="Measurement">
59  * <parameter name="Flux" value="1.0"/>
60  * </element>
61  * <element>
62  * <list>
63  * <string>This is a text</string>
64  * <integer>17</integer>
65  * </list>
66  * </element>
67  *
68  * An XML document is a plain ASCII file. Every XML document begins by a
69  * declaration of the XML version and an optional information about the
70  * encoding of the text.
71  *
72  * The XML document is structured using @b tags. A tag is a markup construct
73  * that begins with @< and ends with @>. Tags come in three flavors:
74  * - start-tags; for example: @<section@>
75  * - end-tags; for example: @</section@>
76  * - empty-element tags; for example: @<line-break /@>
77  *
78  * The header line of an XML document is an empty-element tag. Each tag may
79  * contain an arbitrary number of @b attributes of the form
80  *
81  * version="1.0"
82  *
83  * Alternative quotes ' are also allowed.
84  *
85  * A logical document component which either begins with a start-tag and ends
86  * with a matching end-tag or consists only of an empty-element tag is called
87  * an @b element. The characters between the start- and end-tags, if any, are
88  * the element's content, and may contain markup, including other elements,
89  * which are called @b child @b elements. An example of an element is
90  *
91  *
92  * <string>This is a text</string>
93  *
94  * Another is
95  *
96  * <parameter name="Flux" value="1.0"/>
97  *
98  * This last example has two attributes. The first word in an element is
99  * called the @b element @b name. Every element has a name. Elements can
100  * therefore be accessed by name, however, several elements with the same
101  * name may exist.
102  *
103  * GammaLib implements the XML document in form of a master class GXml
104  * which contains the root node of the document. The root node is
105  * realized by the GXmlDocument class. GXmlDocument derives from GXmlNode,
106  * which defines the abstract interface for all XML nodes. The following
107  * XML nodes exist:
108  * - GXmlElement: implements an element
109  * - GXmlText: implements a text leaf
110  * - GXmlPI: implements a Processing Instruction
111  * - GXmlComment: implement a comment
112  *
113  * XML element attributes are implemented using GXmlAttribute.
114  *
115  * The GXml class provides methods to access the nodes of the XML document,
116  * and to load and save the document from a URL. GXml derives from GContainer
117  * as it behaves like a container class. It does, however, not contain an
118  * explicit list, as the only data member of the class is a single instance
119  * of GXmlDocument. GXmlDocument contains the hierarchical list of all XML
120  * nodes.
121  *
122  * To manipulate the child nodes of GXmlDocument, the usual container class
123  * methods are available. size() returns the number of child nodes that
124  * exist in the XML document root (in the above example there would be two
125  * child elements with name @p element). The child nodes are accessed using
126  * the operator[]. The is_empty() method checks whether the document root has
127  * no children.
128  *
129  * The set() method allows to set a specific child node, the append() method
130  * appends a child node to the XML document root. There is a second variant
131  * of the append() method that appends a element of type GXmlElement to the
132  * XML document root and that returns a pointer to this element. As argument,
133  * this second method takes a text string that defines the element name and
134  * attributes. For example, the first node in the above example could have
135  * been generated using
136  *
137  * GXml xml;
138  * xml.append("element type=\"Measurement\"");
139  *
140  * Note that the @< and @> symbols are not part of the text string that is
141  * passed to the append() method.
142  *
143  * The insert() method inserts a child node at the specified index in the
144  * XML root document. The remove() method removes the child node at the
145  * specified index from the document root. The reserve() method reserves
146  * space for a specified number of child nodes in the XML document root.
147  * And the extend() method appends all child nodes that are found in the
148  * specified argument to the XML document root.
149  *
150  * Most of the nodes encountered in a XML document will be @b element
151  * @b nodes, hence special methods for handling element nodes have been
152  * implemented. The elements() method returns the number of child elements
153  * that are present in the XML document root. A variant that takes a string
154  * argument counts the number of child elements with a given name. The
155  * element() method allows to access the child elements. There are again
156  * two flavours, one that simply takes an index to loop over all child
157  * elements, and another that takes a name and a index to loop over all
158  * child elements of a given name. For element access, non-const and const
159  * variants exist.
160  *
161  * Finally, the load() and save() methods enable loading and saving a XML
162  * document from and to disk. The read() and write() method, which do the
163  * actual job of reading and writing, operate on general Unified Resource
164  * Locators, so that XML documents can also through other media than flat
165  * files.
166  *
167  * The print() method does not print the full XML document into a string
168  * but shows a concise summary that reflects the tree structure. For writing
169  * the document in a string, use the write() method to write in a string URL
170  * object (GUrlString).
171  ***************************************************************************/
172 class GXml : public GContainer {
173 
174  // Friend classes
175  friend class GXmlNode;
176  friend class GXmlDocument;
177  friend class GXmlText;
178 
179 public:
180  // Constructors and destructors
181  GXml(void);
182  GXml(const GXml& xml);
183  explicit GXml(const std::string& xml);
184  explicit GXml(const GXmlDocument& root);
185  virtual ~GXml(void);
186 
187  // Operators
188  GXml& operator=(const GXml& xml);
189  GXmlNode* operator[](const int& index);
190  const GXmlNode* operator[](const int& index) const;
191 
192  // Methods
193  void clear(void);
194  GXml* clone(void) const;
195  std::string classname(void) const;
196  int size(void) const;
197  bool is_empty(void) const;
198  GXmlNode* set(const int& index, const GXmlNode& node);
199  GXmlNode* append(const GXmlNode& node);
200  GXmlElement* append(const std::string& segment);
201  GXmlNode* insert(const int& index, const GXmlNode& node);
202  void remove(const int& index);
203  void reserve(const int& num);
204  void extend(const GXmlNode& node);
205  int elements(void) const;
206  int elements(const std::string& name) const;
207  GXmlElement* element(const int& index);
208  const GXmlElement* element(const int& index) const;
209  GXmlElement* element(const std::string& name);
210  const GXmlElement* element(const std::string& name) const;
211  GXmlElement* element(const std::string& name, const int& index);
212  const GXmlElement* element(const std::string& name, const int& index) const;
213  const GXmlDocument& root(void) const;
214  void root(const GXmlDocument& root);
215  void load(const GFilename& filename);
216  void save(const GFilename& filename) const;
217  void read(const GUrl& url);
218  void write(GUrl& url, const int& indent = 0) const;
219  std::string print(const GChatter& chatter = NORMAL) const;
220  std::string print(const GChatter& chatter = NORMAL,
221  const int& indent = 0) const;
222 
223 protected:
224  // Protected enumerators
225  enum MarkupType {
233  };
234 
235  // Protected methods
236  void init_members(void);
237  void copy_members(const GXml& xml);
238  void free_members(void);
239  void parse(const GUrl& url);
240  void process_markup(GXmlNode** current, const std::string& segment);
241  void process_text(GXmlNode** current, const std::string& segment);
242  MarkupType get_markuptype(const std::string& segment) const;
243 
244  // Protected members
245  GXmlDocument m_root; //!< Root document node
246 };
247 
248 
249 /***********************************************************************//**
250  * @brief Return class name
251  *
252  * @return String containing the class name ("GXml").
253  ***************************************************************************/
254 inline
255 std::string GXml::classname(void) const
256 {
257  return ("GXml");
258 }
259 
260 
261 /***********************************************************************//**
262  * @brief Return number of child nodes
263  *
264  * @return Number of child nodes in node.
265  ***************************************************************************/
266 inline
267 int GXml::size(void) const
268 {
269  return m_root.size();
270 }
271 
272 
273 /***********************************************************************//**
274  * @brief Signals if document has no child nodes
275  *
276  * @return True if document has no child nodes.
277  ***************************************************************************/
278 inline
279 bool GXml::is_empty(void) const
280 {
281  return m_root.is_empty();
282 }
283 
284 
285 /***********************************************************************//**
286  * @brief Return document root
287  *
288  * @return Document root.
289  ***************************************************************************/
290 inline
291 const GXmlDocument& GXml::root(void) const
292 {
293  return m_root;
294 }
295 
296 
297 /***********************************************************************//**
298  * @brief Set document root
299  *
300  * @param[in] root Document root.
301  ***************************************************************************/
302 inline
303 void GXml::root(const GXmlDocument& root)
304 {
305  m_root = root;
306  return;
307 }
308 
309 #endif /* GXML_HPP */
Abstract XML node base class.
Definition: GXmlNode.hpp:57
void read(const GUrl &url)
Read XML document from URL.
Definition: GXml.cpp:603
GFilename filename(void) const
Return filename of XML file.
Definition: GXmlNode.cpp:540
void free_members(void)
Delete class members.
Definition: GXml.cpp:716
XML element node class interface definition.
void save(const GFilename &filename) const
Save XML document into file.
Definition: GXml.cpp:576
MarkupType
Definition: GXml.hpp:225
GXmlDocument m_root
Root document node.
Definition: GXml.hpp:245
std::string print(const GChatter &chatter=NORMAL) const
Print XML object.
Definition: GXml.cpp:669
XML element node class.
Definition: GXmlElement.hpp:47
void clear(void)
Clear XML object.
Definition: GXml.cpp:232
void reserve(const int &num)
Reserve space for child nodes in XML document root.
Definition: GXml.cpp:346
void load(const GFilename &filename)
Load XML document from file.
Definition: GXml.cpp:537
void write(GUrl &url, const int &indent=0) const
Write XML document into URL.
Definition: GXml.cpp:625
GXmlNode * insert(const int &index, const GXmlNode &node)
Insert child node into XML document root.
Definition: GXml.cpp:315
Abstract URL base class interface definition.
Abstract URL base class.
Definition: GUrl.hpp:44
void extend(const GXmlNode &node)
Append all XML child nodes from another XML node in the XML document root.
Definition: GXml.cpp:366
bool is_empty(void) const
Signals if document has no child nodes.
Definition: GXml.hpp:279
virtual int size(void) const
Return number of child nodes.
Definition: GXmlNode.hpp:133
GXmlElement * element(const int &index)
Return pointer to child element.
Definition: GXml.cpp:419
int elements(void) const
Return number of child elements in XML document root.
Definition: GXml.cpp:384
void init_members(void)
Initialise class members.
Definition: GXml.cpp:688
XML class.
Definition: GXml.hpp:172
Filename class.
Definition: GFilename.hpp:62
XML text node class.
Definition: GXmlText.hpp:43
GXmlNode * set(const int &index, const GXmlNode &node)
Set child node in XML document root.
Definition: GXml.cpp:264
std::string classname(void) const
Return class name.
Definition: GXml.hpp:255
GChatter
Definition: GTypemaps.hpp:33
GXmlNode * operator[](const int &index)
Return pointer to child of XML document root element.
Definition: GXml.cpp:198
XML document node class interface definition.
void copy_members(const GXml &xml)
Copy class members.
Definition: GXml.cpp:703
const GXmlDocument & root(void) const
Return document root.
Definition: GXml.hpp:291
void process_markup(GXmlNode **current, const std::string &segment)
Process markup segment.
Definition: GXml.cpp:883
XML text node class interface definition.
XML document node class.
void parse(const GUrl &url)
Parse XML URL.
Definition: GXml.cpp:735
GXml * clone(void) const
Clone XML object.
Definition: GXml.cpp:248
GXml(void)
Void constructor.
Definition: GXml.cpp:65
virtual bool is_empty(void) const
Signals if node has no child nodes.
Definition: GXmlNode.hpp:145
GXml & operator=(const GXml &xml)
Assignment operator.
Definition: GXml.cpp:168
MarkupType get_markuptype(const std::string &segment) const
Get Markup type of segment.
Definition: GXml.cpp:1039
Definition of interface for container classes.
int size(void) const
Return number of child nodes.
Definition: GXml.hpp:267
virtual ~GXml(void)
Destructor.
Definition: GXml.cpp:146
Abstract XML node base class interface definition.
void process_text(GXmlNode **current, const std::string &segment)
Process text segment.
Definition: GXml.cpp:1011
Interface class for container classes.
Definition: GContainer.hpp:52
GXmlNode * append(const GXmlNode &node)
Append child node to XML document root.
Definition: GXml.cpp:279