File: xml.h

package info (click to toggle)
tqsllib 2.0-8
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 2,460 kB
  • ctags: 1,081
  • sloc: sh: 8,309; cpp: 7,980; xml: 4,068; makefile: 102
file content (176 lines) | stat: -rw-r--r-- 6,156 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/***************************************************************************
                          xml.h  -  description
                             -------------------
    begin                : Fri Aug 9 2002
    copyright            : (C) 2002 by ARRL
    author               : Jon Bloom
    email                : jbloom@arrl.org
    revision             : $Id: xml.h,v 1.3 2005/02/23 18:09:27 ke3z Exp $
 ***************************************************************************/

#ifndef __xml_h
#define __xml_h

#include <string>
#include <map>
#include <vector>
#include <utility>
#include <expat.h>

namespace tqsllib {

class XMLElement;

typedef std::multimap<std::string,XMLElement> XMLElementList;
typedef std::map<std::string,std::string> XMLElementAttributeList;

/** Encapsulates an XML element
  *
  * An XMLElement comprises a name, the enclosed text, an optional set of
  * attributes, and an optional list of contained elements.
  *
  * Having a list of contained elements allows construction of the XML
  * document tree structure. In most cases, the structure will be populated
  * by a call to parseFile().
  */
class XMLElement {
public:
	XMLElement() : _name(""), _text(""), _pretext("") {}
	/// Constructor initializes element name
	XMLElement(const std::string& name) : _text(""), _pretext("") { _name = name; }
	/// Clear the element of all data
	void clear();
	/// Set the element name
	void setElementName(const std::string& name) { _name = name; }
	/// Get the element name
	std::string getElementName() const { return _name; }
	/// Set an attribute.
    /** Attributes are treated as unique key/value pairs. */
	void setAttribute(const std::string& key, const std::string& value);
	/// Get an attribute by its key.
	/** Returns a pair where:
      *
      * \li \c getAttribute().first := the attribute's value
      * \li \c getAttribute().second := a bool, true if the atrtribute key exists
      */
	std::pair<std::string,bool> getAttribute(const std::string& key);
	/// Add an element to the list of contained subelements
	XMLElementList::iterator addElement(const XMLElement& element);
	XMLElementAttributeList& getAttributeList() { return _attributes; }
	XMLElementList& getElementList() { return _elements; }
	/// Parse an XML file and add its element tree to this element
	bool parseFile(const char *filename);
	/// Get the first attribute of the element
    /** Provides the attribute key and value. Returns \c false if the
      * element contains no attributes */
	bool getFirstAttribute(std::string& key, std::string& attr);
	/// Get the next attribute of the element
    /** Should be called only after calling getFirstAttribute and getting
      * a return value of \c true.
      * Provides the attribute key and value. Returns \c false if the
      * element contains no more attributes */
	bool getNextAttribute(std::string& key, std::string& attr);
	/// Get the first contained element named \c name.
    /** Returns \c false if the element contains no elements named \c name */
	bool getFirstElement(const std::string& name, XMLElement&);
	/// Get the first contained element.
    /** Returns \c false if the element contains no elements */
	bool getFirstElement(XMLElement&);
	/// Get the next contained element.
    /** Should be called only after calling getFirstElement and getting
      * a return value of \c true. If the getFirstElement that takes an
      * element name was called, getNextElement will return \c false when there
      * are no more elements of that name in the element list.
	  *
      * Returns \c false if the element contains no more elements */
	bool getNextElement(XMLElement&);
	/// Set the contained text string
	void setText(const std::string& s) { _text = s; }
	/// Get the contained text string.
	/** Note that this string comprises the text contained in this
      * element only, not any text contained in elements on the
      * element list; they each have their own contained text.
      */
	std::string getText() const { return _text; }
	void setPretext(const std::string& s) { _pretext = s; }
	std::string getPretext() const { return _pretext; }

private:
	static void xml_start(void *data, const XML_Char *name, const XML_Char **atts);
	static void xml_end(void *data, const XML_Char *name);
	static void xml_text(void *data, const XML_Char *text, int len);
	std::string _name, _text, _pretext;
	XMLElementAttributeList _attributes;
	XMLElementList _elements;
	std::vector<XMLElementList::iterator> _parsingStack;
	XMLElementList::iterator _iter;
	bool _iterByName;
	std::string _iterName;
	XMLElementAttributeList::iterator _aiter;
};

inline void XMLElement::clear() {
	_name = _text = _pretext = _iterName = "";
	_attributes.clear();
	_elements.clear();
	_parsingStack.clear();
}

inline void
XMLElement::setAttribute(const std::string& key, const std::string& value) {
	_attributes[key] = value;
}

inline XMLElementList::iterator
XMLElement::addElement(const XMLElement& element) {
	XMLElementList::iterator it = _elements.insert(make_pair(element.getElementName(), element));
	return it;
}

inline bool
XMLElement::getFirstElement(XMLElement& element) {
	_iterByName = false;
	_iter = _elements.begin();
	return getNextElement(element);
}

inline bool
XMLElement::getFirstElement(const std::string& name, XMLElement& element) {
	_iterName = name;
	_iterByName = true;
	_iter = _elements.find(_iterName);
	return getNextElement(element);
}

inline bool
XMLElement::getNextElement(XMLElement& element) {
	if (_iter == _elements.end())
		return false;
	if (_iterByName && _iter->second.getElementName() != _iterName)
		return false;
	element = _iter->second;
	++_iter;
	return true;
}

inline bool
XMLElement::getFirstAttribute(std::string& key, std::string& attr) {
	_aiter = _attributes.begin();
	return getNextAttribute(key, attr);
}

inline bool
XMLElement::getNextAttribute(std::string& key, std::string& attr) {
	if (_aiter == _attributes.end())
		return false;
	key = _aiter->first;
	attr = _aiter->second;
	++_aiter;
	return true;
}

std::ostream& operator<< (std::ostream& stream, XMLElement& el);

}	// namespace tqsllib

#endif // __xml_h