GammaLib 2.0.0
Loading...
Searching...
No Matches
GXmlElement.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * GXmlElement.cpp - XML element node class implementation *
3 * ----------------------------------------------------------------------- *
4 * copyright (C) 2010-2021 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 GXmlElement.cpp
23 * @brief XML element node class implementation
24 * @author Juergen Knoedlseder
25 */
26
27/* __ Includes ___________________________________________________________ */
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31#include "GTools.hpp"
32#include "GException.hpp"
33#include "GFilename.hpp"
34#include "GXmlDocument.hpp"
35#include "GXmlElement.hpp"
36#include "GXmlText.hpp"
37
38/* __ Method name definitions ____________________________________________ */
39#define G_VALUE "GXmlElement::value()"
40#define G_ATTRIBUTE "GXmlElement::attribute(int&)"
41#define G_PARSE_START "GXmlElement::parse_start(std::string&)"
42#define G_PARSE_STOP "GXmlElement::parse_stop(std::string&)"
43#define G_PARSE_ATTRIBUTE "GXmlElement::parse_attribute(size_t*, "\
44 "std::string&)"
45
46/* __ Constants __________________________________________________________ */
47const int g_indent = 2; //!< Indent for XML file writing
48
49/* __ Macros _____________________________________________________________ */
50
51/* __ Coding definitions _________________________________________________ */
52
53/* __ Debug definitions __________________________________________________ */
54
55
56/*==========================================================================
57 = =
58 = Constructors/destructors =
59 = =
60 ==========================================================================*/
61
62/***********************************************************************//**
63 * @brief Void constructor
64 ***************************************************************************/
66{
67 // Initialise members
69
70 // Return
71 return;
72}
73
74
75/***********************************************************************//**
76 * @brief Copy constructor
77 *
78 * @param[in] node XML element.
79 ***************************************************************************/
81{
82 // Initialise members
84
85 // Copy members
86 copy_members(node);
87
88 // Return
89 return;
90}
91
92
93/***********************************************************************//**
94 * @brief Segment constructor
95 *
96 * @param[in] segment XML segment.
97 *
98 * Constructs a XML element from a text @p segment. The text segment is
99 * parsed and the element name and attributes are extracted using the
100 * parse_start() method.
101 ***************************************************************************/
102GXmlElement::GXmlElement(const std::string& segment) : GXmlNode()
103{
104 // Initialise members
105 init_members();
106
107 // Parse start element
108 parse_start(segment);
109
110 // Return
111 return;
112}
113
114
115/***********************************************************************//**
116 * @brief Integer value constructor
117 *
118 * @param[in] name Element name.
119 * @param[in] value Integer value.
120 *
121 * Constructs a XML value element of the form
122 *
123 * <name>value</name>
124 ***************************************************************************/
125GXmlElement::GXmlElement(const std::string& name,
126 const int& value) : GXmlNode()
127{
128 // Initialise members
129 init_members();
130
131 // Set element name
132 m_name = name;
133
134 // Append text element with value
136
137 // Return
138 return;
139}
140
141
142/***********************************************************************//**
143 * @brief Floating point value constructor
144 *
145 * @param[in] name Element name.
146 * @param[in] value Floating point value.
147 *
148 * Constructs a XML value element of the form
149 *
150 * <name>value</name>
151 ***************************************************************************/
152GXmlElement::GXmlElement(const std::string& name,
153 const double& value) : GXmlNode()
154{
155 // Initialise members
156 init_members();
157
158 // Set element name
159 m_name = name;
160
161 // Append text element with value
163
164 // Return
165 return;
166}
167
168
169/***********************************************************************//**
170 * @brief String value constructor
171 *
172 * @param[in] name Element name.
173 * @param[in] value String value.
174 *
175 * Constructs a XML value element of the form
176 *
177 * <name>value</name>
178 ***************************************************************************/
179GXmlElement::GXmlElement(const std::string& name,
180 const std::string& value) : GXmlNode()
181{
182 // Initialise members
183 init_members();
184
185 // Set element name
186 m_name = name;
187
188 // Append text element with value
189 this->append(GXmlText(value));
190
191 // Return
192 return;
193}
194
195
196/***********************************************************************//**
197 * @brief Destructor
198 ***************************************************************************/
200{
201 // Free members
202 free_members();
203
204 // Return
205 return;
206}
207
208
209/*==========================================================================
210 = =
211 = Operators =
212 = =
213 ==========================================================================*/
214
215/***********************************************************************//**
216 * @brief Assignment operator
217 *
218 * @param[in] node XML element.
219 * @return XML element.
220 ***************************************************************************/
222{
223 // Execute only if object is not identical
224 if (this != &node) {
225
226 // Copy base class members
227 this->GXmlNode::operator=(node);
228
229 // Free members
230 free_members();
231
232 // Initialise members
233 init_members();
234
235 // Copy members
236 copy_members(node);
237
238 } // endif: object was not identical
239
240 // Return
241 return *this;
242}
243
244
245/*==========================================================================
246 = =
247 = Public methods =
248 = =
249 ==========================================================================*/
250
251 /***********************************************************************//**
252 * @brief Clear XML element
253 *
254 * Resets the XML element to a clean initial state.
255 ***************************************************************************/
257{
258 // Free class members (base and derived classes, derived class first)
259 free_members();
261
262 // Initialise members
264 init_members();
265
266 // Return
267 return;
268}
269
270
271/***********************************************************************//**
272 * @brief Clone XML element
273 *
274 * @return Pointer to deep copy of XML element.
275 ***************************************************************************/
277{
278 // Clone element
279 return new GXmlElement(*this);
280}
281
282
283/***********************************************************************//**
284 * @brief Return string value
285 *
286 * @return String value.
287 *
288 * @exception GException::invalid_value
289 * Element does not contain a single text element.
290 *
291 * Returns the string value of the text element in case that the element
292 * contains one text element. An exception is returned in case that the
293 * element does not contain a text element.
294 ***************************************************************************/
295std::string GXmlElement::value(void) const
296{
297 // Throw an exception if the element does not contain a single element
298 if (size() != 1) {
299 std::string msg = "Method requires a XML element instance that "
300 "contains a single child, but this instance "
301 "contains "+gammalib::str(size())+" childs. "
302 "Please specify a valid XML element.";
304 }
305
306 // Throw an exception if the element does not contain a text element
307 const GXmlText *text = dynamic_cast<const GXmlText*>((*this)[0]);
308 if (text == NULL) {
309 std::string msg = "XML element instance does not contain a text "
310 "element. Please specify a valid XML element.";
312 }
313
314 // Return text string as value
315 return (text->text());
316}
317
318
319/***********************************************************************//**
320 * @brief Return attribute
321 *
322 * @param[in] index Attribute index [0,...,attributes()[.
323 * @return Pointer to attribute.
324 *
325 * @exception GException::out_of_range
326 * Index out of range.
327 ***************************************************************************/
328const GXmlAttribute* GXmlElement::attribute(const int& index) const
329{
330 // Throw exception if index is out of range
331 #if defined(G_RANGE_CHECK)
332 if (index < 0 || index >= attributes()) {
333 throw GException::out_of_range(G_ATTRIBUTE, "Attribute index",
334 index, attributes());
335 }
336 #endif
337
338 // Return pointer to attribute
339 return (m_attr[index]);
340}
341
342
343/***********************************************************************//**
344 * @brief Return attribute value
345 *
346 * @param[in] name Attribute name.
347 * @return String containing attribute value.
348 *
349 * Returns the value of the attribute @p name. If the requested attribute was
350 * not found an empty string is returned.
351 ***************************************************************************/
352std::string GXmlElement::attribute(const std::string& name) const
353{
354 // Initialise empty value (i.e. attribute not found)
355 std::string value = "";
356
357 // Search attribute value in list of attributes
358 for (int i = 0; i < m_attr.size(); ++i) {
359 if (m_attr[i]->name() == name) {
360 value = m_attr[i]->value();
361 break;
362 }
363 }
364
365 // Return value
366 return value;
367}
368
369
370/***********************************************************************//**
371 * @brief Set attribute value
372 *
373 * @param[in] name Attribute name.
374 * @param[in] value Attribute value.
375 *
376 * Sets an attribute of the element. If the attribute name exists the value
377 * is modified. If the attribute does not yet exist it is created and
378 * added to the list of attributes.
379 *
380 * Note that this logical assures that only one attribute with a given name
381 * will exist in the element.
382 ***************************************************************************/
383void GXmlElement::attribute(const std::string& name, const std::string& value)
384{
385 // Initialise attribute NULL pointer
386 GXmlAttribute* attr = NULL;
387
388 // Search attribute name in list of attributes
389 for (int i = 0; i < m_attr.size(); ++i) {
390 if (m_attr[i]->name() == name) {
391 attr = m_attr[i];
392 break;
393 }
394 }
395
396 // If no attribute with specified name has been found then add a new
397 // attribute to the list of attributes
398 if (attr == NULL) {
399 attr = new GXmlAttribute;
400 attr->name(name);
401 m_attr.push_back(attr);
402 }
403
404 // Set or update value of attribute
405 attr->value(value);
406
407 // Return
408 return;
409}
410
411
412/***********************************************************************//**
413 * @brief Check if element has a given attribute
414 *
415 * @param[in] name Attribute name.
416 * @return True if attribute exists, false otherwise.
417 *
418 * Checks whether the element contains an attribute with @p name. If the
419 * attribute was found true is returned, false otherwise.
420 ***************************************************************************/
421bool GXmlElement::has_attribute(const std::string& name) const
422{
423 // Initialise found flag
424 bool found = false;
425
426 // Search attribute value in list of attributes
427 for (int i = 0; i < m_attr.size(); ++i) {
428 if (m_attr[i]->name() == name) {
429 found = true;
430 break;
431 }
432 }
433
434 // Return found flag
435 return found;
436}
437
438
439/***********************************************************************//**
440 * @brief Remove attribute from element
441 *
442 * @param[in] name Attribute name.
443 *
444 * Remove the attribute with @p name from the XML element. If the requested
445 * attribute was not found the method does nothing.
446 ***************************************************************************/
447void GXmlElement::remove_attribute(const std::string& name)
448{
449 // Do nothing if there are no attributes
450 if (!m_attr.empty()) {
451
452 // Store number of attributes.
453 int num = m_attr.size();
454
455 // Search attribute name in list of attributes and erase attribute
456 // when it has been found. Note that if several attributes with the
457 // same name exist (which should never be the case!), only the
458 // first attribute is removed
459 for (int i = 0; i < num; ++i) {
460 if (m_attr[i]->name() == name) {
461 m_attr.erase(m_attr.begin() + i);
462 break;
463 }
464 }
465
466 } // endif: there were attributes
467
468 // Return
469 return;
470}
471
472
473/***********************************************************************//**
474 * @brief Write element into URL
475 *
476 * @param[in] url Unified Resource Locator.
477 * @param[in] indent Text indentation.
478 *
479 * Writes the element into a Unified Resource Locator.
480 ***************************************************************************/
481void GXmlElement::write(GUrl& url, const int& indent) const
482{
483 // Prepend indentation
484 for (int k = 0; k < indent; ++k) {
485 url.printf(" ");
486 }
487
488 // Write element name into URL
489 url.printf("<%s", m_name.c_str());
490
491 // Write attributes into URL
492 for (int k = 0; k < m_attr.size(); ++k) {
493 m_attr[k]->write(url);
494 }
495
496 // If there are no children then write an empty tag
497 if (is_empty()) {
498 url.printf(" />\n");
499 }
500
501 // ... otherwise finish start tag, write children and write end tag
502 else {
503
504 // Case A: The element contains a single text leaf
505 if ((m_nodes.size() == 1) && (m_nodes[0]->type() == NT_TEXT)) {
506
507 // Finish start tag
508 url.printf(">");
509
510 // Write text leaf
511 m_nodes[0]->write(url, 0);
512
513 // Write end tag
514 url.printf("</%s>\n", m_name.c_str());
515 }
516
517 // Case B: ... otherwise it contains markup
518 else {
519
520 // Finish start tag
521 url.printf(">\n");
522
523 // Write children in file
524 for (int i = 0; i < m_nodes.size(); ++i) {
525 m_nodes[i]->write(url, indent+g_indent);
526 if (m_nodes[i]->type() == NT_TEXT) {
527 url.printf("\n");
528 }
529 }
530
531 // Write end tag
532 for (int k = 0; k < indent; ++k) {
533 url.printf(" ");
534 }
535 url.printf("</%s>\n", m_name.c_str());
536
537 } // endelse: element contained markup
538
539 } // endelse: finished start tag
540
541 // Return
542 return;
543}
544
545
546/***********************************************************************//**
547 * @brief Print XML element
548 *
549 * @param[in] chatter Chattiness.
550 * @param[in] indent Text indentation.
551 * @return String containing XML element
552 ***************************************************************************/
553std::string GXmlElement::print(const GChatter& chatter,
554 const int& indent) const
555{
556 // Allocate result string
557 std::string result;
558
559 // Continue only if chatter is not silent
560 if (chatter != SILENT) {
561
562 // Initialise result string
563 result = gammalib::fill(" ", indent);
564
565 // Append element to string
566 result.append("GXmlElement::"+m_name);
567 for (int k = 0; k < m_attr.size(); ++k) {
568 result.append(m_attr[k]->print(chatter));
569 }
570
571 // Append children
572 for (int i = 0; i < m_nodes.size(); ++i) {
573 result.append("\n" + m_nodes[i]->print(chatter, indent+g_indent));
574 }
575
576 } // endif: chatter was not silent
577
578 // Return
579 return result;
580}
581
582
583/*==========================================================================
584 = =
585 = Private methods =
586 = =
587 ==========================================================================*/
588
589/***********************************************************************//**
590 * @brief Initialise class members
591 ***************************************************************************/
593{
594 // Initialise members
595 m_name.clear();
596 m_attr.clear();
597
598 // Return
599 return;
600}
601
602
603/***********************************************************************//**
604 * @brief Copy class members
605 *
606 * @param[in] node XML element.
607 *
608 * This method copies all class members. XML attributes are cloned.
609 ***************************************************************************/
611{
612 // Copy members
613 m_name = node.m_name;
614
615 // Copy attribute container
616 m_attr.clear();
617 for (int i = 0; i < node.m_attr.size(); ++i) {
618 m_attr.push_back((node.m_attr[i]->clone()));
619 }
620
621 // Return
622 return;
623}
624
625
626/***********************************************************************//**
627 * @brief Delete class members
628 *
629 * As container classes that hold pointers need to handle themselves the
630 * proper deallocation of memory, we loop here over all pointers and make
631 * sure that we deallocate the associated nodes.
632 ***************************************************************************/
634{
635 // Free attributes
636 for (int i = 0; i < m_attr.size(); ++i) {
637 delete m_attr[i];
638 m_attr[i] = NULL;
639 }
640
641 // Return
642 return;
643}
644
645
646/***********************************************************************//**
647 * @brief Parse element start segment string
648 *
649 * @param[in] segment Segment string.
650 *
651 * @exception GException::xml_syntax_error
652 * XML syntax error.
653 *
654 * Parse the segment string and set class members based on the information
655 * that is found. The method also performs syntax checking. It does not
656 * require brackets to be set.
657 ***************************************************************************/
658void GXmlElement::parse_start(const std::string& segment)
659{
660 // Initialize position check
661 std::size_t pos_start = 0;
662
663 // Get length of segment
664 int n = segment.length();
665
666 // Throw an error is segment is empty
667 if (n < 1) {
668 std::string msg = "Empty XML segment encountered. Please verify the "
669 "XML format.";
671 }
672
673 // If string starts with brackets then check that the brackets are
674 // valid comment brackets
675 if (segment[0] == '<') {
676 if (n < 2 || (segment.compare(0,1,"<") != 0) ||
677 (segment.compare(n-1,1,">") != 0)) {
678 std::string msg = "Invalid tag brackets encountered in XML "
679 "segment \""+segment+"\". Please verify the "
680 "XML format.";
682 }
683 pos_start = 1;
684 } // endif: there were brackets
685
686 // Extract element name
687 std::size_t pos = segment.find_first_of("\x20\x09\x0d\x0a>", 1);
688 if (pos == pos_start) {
689 std::string msg = "Whitespace before element name encountered in XML "
690 "segment \""+segment+"\". Please verify the "
691 "XML format.";
693 }
694 if (pos == std::string::npos) {
695 if (pos_start == 1) {
696 std::string msg = "No element name found in XML segment \""+
697 segment+"\". Please verify the XML format.";
699 }
700 }
701 m_name = segment.substr(pos_start, pos-pos_start);
702
703 // Extract attributes
704 while (pos != std::string::npos) {
705 parse_attribute(&pos, segment);
706 }
707
708 // Return
709 return;
710}
711
712
713/***********************************************************************//**
714 * @brief Parse element stop segment string
715 *
716 * @param[in] segment Segment string.
717 *
718 * @exception GException::xml_syntax_error
719 * XML syntax error.
720 *
721 * Parse the stop segment string and verify the syntax.
722 ***************************************************************************/
723void GXmlElement::parse_stop(const std::string& segment)
724{
725 // Get length of segment
726 int n = segment.length();
727
728 // Check on existence of brackets
729 if (n < 3 || (segment.compare(0,2,"</") != 0) ||
730 (segment.compare(n-1,1,">") != 0)) {
731 std::string msg = "Incorrect or missing tag brackets encountered in "
732 "XML segment \""+segment+"\". Please verify the "
733 "XML format.";
735 }
736
737 // Extract and verify element name
738 size_t pos = segment.find_first_of("\x20\x09\x0d\x0a>", 2);
739 if (pos == 2) {
740 std::string msg = "Whitespace encountered after \"</\" in XML "
741 "segment \""+segment+"\". Please verify the XML "
742 "format.";
744 }
745 if (pos == std::string::npos) {
746 std::string msg = "No element name found in XML segment \""+
747 segment+"\". Please verify the XML format.";
749 }
750 std::string name = segment.substr(2, pos-2);
751 if (name != m_name) {
752 std::string msg = "Element name \""+name+"\" found in stop tag in XML "
753 "segment \""+segment+"\" while start tag has name "
754 "\""+m_name+"\". Please verify the XML format.";
756 }
757
758 // Verify that no further characters exist in element stop tag
759 size_t pos2 = segment.find_first_of("\x20\x09\x0d\x0a>", pos);
760 if (pos2 != n-1) {
761 std::string msg = "Invalid characters encountered after element name "
762 "in XML segment \""+segment+"\". Please verify the "
763 "XML format.";
765 }
766
767 // Return
768 return;
769}
770
771
772/***********************************************************************//**
773 * @brief Parse element attribute
774 *
775 * @param[in] pos Start position in string.
776 * @param[in] segment Segment string.
777 *
778 * @exception GException::invalid_value
779 * XML syntax error.
780 *
781 * Parse the segment string for one attribute, and if attribute was found,
782 * attach it to element.
783 *
784 * @todo Verify XML validity of attribute name and value
785 ***************************************************************************/
786void GXmlElement::parse_attribute(size_t* pos, const std::string& segment)
787{
788 // Main loop
789 do {
790 // Get substring for error message
791 std::string error = segment.substr(*pos, segment.length()-*pos);
792
793 // Find first character of name substring
794 std::size_t pos_name_start = segment.find_first_not_of("\x20\x09\x0d\x0a/>?", *pos);
795 if (pos_name_start == std::string::npos) {
796 *pos = std::string::npos;
797 continue;
798 }
799
800 // Find end of name substring
801 std::size_t pos_name_end = segment.find_first_of("\x20\x09\x0d\x0a=", pos_name_start);
802 if (pos_name_end == std::string::npos) {
803 std::string msg = "Invalid or missing attribute name encountered "
804 "in XML segment \""+error+"\". Please verify "
805 "the XML format.";
807 }
808
809 // Find '=' character
810 std::size_t pos_equal = segment.find_first_of("=", pos_name_end);
811 if (pos_equal == std::string::npos) {
812 std::string msg = "Missing \"=\" sign for attribute encountered "
813 "in XML segment \""+error+"\". Please verify "
814 "the XML format.";
816 }
817
818 // Find start of value substring
819 std::size_t pos_value_start = segment.find_first_of("\x22\x27", pos_equal);
820 if (pos_value_start == std::string::npos) {
821 std::string msg = "Invalid or missing attribute value start "
822 "hyphen encountered in XML segment \""+
823 error+"\". Please verify the XML format.";
825 }
826
827 // Save hyphen character and step forward one character
828 std::string hyphen = segment.substr(pos_value_start, 1);
829 pos_value_start++;
830 if (pos_value_start >= segment.length()) {
831 std::string msg = "Invalid or missing attribute value encountered "
832 "in XML segment \""+error+"\". Please verify "
833 "the XML format.";
835 }
836
837 // Find end of value substring
838 std::size_t pos_value_end = segment.find_first_of(hyphen, pos_value_start);
839 if (pos_value_end == std::string::npos) {
840 std::string msg = "Invalid or missing attribute value end hyphen "
841 "encountered in XML segment \""+error+
842 "\". Please verify the XML format.";
844 }
845
846 // Get name substring
847 std::size_t n_name = pos_name_end - pos_name_start;
848 if (n_name < 1) {
849 std::string msg = "Invalid or missing attribute name encountered "
850 "in XML segment \""+error+"\". Please verify "
851 "the XML format.";
853 }
854 std::string name = segment.substr(pos_name_start, n_name);
855
856 //@todo Check XML validity of attribute name
857
858 // Get value substring length
859 std::size_t n_value = pos_value_end - pos_value_start;
860 std::string value = segment.substr(pos_value_start-1, n_value+2);
861
862 //@todo Check XML validity of attribute value
863
864 // Allocate, set and append new attribute to element
866 m_attr.push_back(attr);
867
868 // Update segment pointer
869 pos_value_end++;
870 if (pos_value_end >= segment.length()) {
871 pos_value_end = std::string::npos;
872 }
873 *pos = pos_value_end;
874
875 } while (0);
876
877 // Return
878 return;
879}
Exception handler interface definition.
Filename class interface definition.
#define G_VALUE
Gammalib tools definition.
GChatter
Definition GTypemaps.hpp:33
@ SILENT
Definition GTypemaps.hpp:34
XML document node class interface definition.
#define G_PARSE_STOP
const int g_indent
Indent for XML file writing.
#define G_PARSE_START
#define G_ATTRIBUTE
#define G_PARSE_ATTRIBUTE
XML element node class interface definition.
XML text node class interface definition.
Abstract URL base class.
Definition GUrl.hpp:44
virtual void printf(const char *format,...)=0
XML attribute class.
const std::string & value(void) const
Return attribute value.
const std::string & name(void) const
Return attribute name.
XML element node class.
void parse_stop(const std::string &segment)
Parse element stop segment string.
std::string m_name
Element name.
std::vector< GXmlAttribute * > m_attr
Attributes.
virtual void clear(void)
Clear XML element.
void parse_start(const std::string &segment)
Parse element start segment string.
const GXmlAttribute * attribute(const int &index) const
Return attribute.
virtual ~GXmlElement(void)
Destructor.
void free_members(void)
Delete class members.
virtual void write(GUrl &url, const int &indent=0) const
Write element into URL.
GXmlElement(void)
Void constructor.
GXmlElement & operator=(const GXmlElement &node)
Assignment operator.
void copy_members(const GXmlElement &node)
Copy class members.
bool has_attribute(const std::string &name) const
Check if element has a given attribute.
void parse_attribute(size_t *pos, const std::string &segment)
Parse element attribute.
std::string value(void) const
Return string value.
void remove_attribute(const std::string &name)
Remove attribute from element.
virtual GXmlElement * clone(void) const
Clone XML element.
const std::string & name(void) const
Return XML element name.
virtual NodeType type(void) const
Return XML node type.
int attributes(void) const
Return number of attributes.
virtual std::string print(const GChatter &chatter=NORMAL, const int &indent=0) const
Print XML element.
void init_members(void)
Initialise class members.
Abstract XML node base class.
Definition GXmlNode.hpp:57
virtual GXmlNode * append(const GXmlNode &node)
Append XML child node.
Definition GXmlNode.cpp:287
GXmlNode & operator=(const GXmlNode &node)
Assignment operator.
Definition GXmlNode.cpp:118
std::vector< GXmlNode * > m_nodes
Pointer to child nodes.
Definition GXmlNode.hpp:123
void free_members(void)
Delete class members.
Definition GXmlNode.cpp:921
virtual bool is_empty(void) const
Signals if node has no child nodes.
Definition GXmlNode.hpp:145
virtual int size(void) const
Return number of child nodes.
Definition GXmlNode.hpp:133
void init_members(void)
Initialise class members.
Definition GXmlNode.cpp:880
XML text node class.
Definition GXmlText.hpp:43
const std::string & text(void) const
Return text.
Definition GXmlText.hpp:97
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition GTools.cpp:489
std::string fill(const std::string &s, const int &n)
Fill string with n strings of same type.
Definition GTools.cpp:1044