b8078dce14fa46abb9e3d29c7dd1bfbf19a9334c
1 #ifndef __PEDRODOM_H__
2 #define __PEDRODOM_H__
3 /*
4 * API for the Pedro mini-DOM parser and tree
5 *
6 * Authors:
7 * Bob Jamison
8 *
9 * Copyright (C) 2005-2007 Bob Jamison
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
26 #include <glib.h>
28 #include <string>
29 #include <vector>
32 namespace Pedro
33 {
35 typedef std::string DOMString;
36 typedef unsigned int XMLCh;
39 class Namespace
40 {
41 public:
42 Namespace()
43 {}
45 Namespace(const DOMString &prefixArg, const DOMString &namespaceURIArg)
46 {
47 prefix = prefixArg;
48 namespaceURI = namespaceURIArg;
49 }
51 Namespace(const Namespace &other)
52 {
53 assign(other);
54 }
56 Namespace &operator=(const Namespace &other)
57 {
58 assign(other);
59 return *this;
60 }
62 virtual ~Namespace()
63 {}
65 virtual DOMString getPrefix()
66 { return prefix; }
68 virtual DOMString getNamespaceURI()
69 { return namespaceURI; }
71 protected:
73 void assign(const Namespace &other)
74 {
75 prefix = other.prefix;
76 namespaceURI = other.namespaceURI;
77 }
79 DOMString prefix;
80 DOMString namespaceURI;
82 };
84 class Attribute
85 {
86 public:
87 Attribute()
88 {}
90 Attribute(const DOMString &nameArg, const DOMString &valueArg)
91 {
92 name = nameArg;
93 value = valueArg;
94 }
96 Attribute(const Attribute &other)
97 {
98 assign(other);
99 }
101 Attribute &operator=(const Attribute &other)
102 {
103 assign(other);
104 return *this;
105 }
107 virtual ~Attribute()
108 {}
110 virtual DOMString getName()
111 { return name; }
113 virtual DOMString getValue()
114 { return value; }
116 protected:
118 void assign(const Attribute &other)
119 {
120 name = other.name;
121 value = other.value;
122 }
124 DOMString name;
125 DOMString value;
127 };
130 class Element
131 {
132 friend class Parser;
134 public:
135 Element()
136 {
137 parent = NULL;
138 }
140 Element(const DOMString &nameArg)
141 {
142 parent = NULL;
143 name = nameArg;
144 }
146 Element(const DOMString &nameArg, const DOMString &valueArg)
147 {
148 parent = NULL;
149 name = nameArg;
150 value = valueArg;
151 }
153 Element(const Element &other)
154 {
155 assign(other);
156 }
158 Element &operator=(const Element &other)
159 {
160 assign(other);
161 return *this;
162 }
164 virtual Element *clone();
166 virtual ~Element()
167 {
168 for (unsigned int i=0 ; i<children.size() ; i++)
169 delete children[i];
170 }
172 virtual DOMString getName()
173 { return name; }
175 virtual DOMString getValue()
176 { return value; }
178 Element *getParent()
179 { return parent; }
181 Element *getFirstChild()
182 { return (children.size() == 0) ? NULL : children[0]; }
184 std::vector<Element *> getChildren()
185 { return children; }
187 std::vector<Element *> findElements(const DOMString &name);
189 DOMString getAttribute(const DOMString &name);
191 std::vector<Attribute> &getAttributes()
192 { return attributes; }
194 DOMString getTagAttribute(const DOMString &tagName, const DOMString &attrName);
196 DOMString getTagValue(const DOMString &tagName);
198 void addChild(Element *child);
200 void addAttribute(const DOMString &name, const DOMString &value);
202 void addNamespace(const DOMString &prefix, const DOMString &namespaceURI);
204 bool exists(const DOMString &name)
205 { return (findElements(name).size() > 0); }
207 /**
208 * Prettyprint an XML tree to an output stream. Elements are indented
209 * according to element hierarchy.
210 * @param f a stream to receive the output
211 * @param elem the element to output
212 */
213 void writeIndented(FILE *f);
215 /**
216 * Prettyprint an XML tree to standard output. This is the equivalent of
217 * writeIndented(stdout).
218 * @param elem the element to output
219 */
220 void print();
222 protected:
224 void assign(const Element &other)
225 {
226 parent = other.parent;
227 children = other.children;
228 attributes = other.attributes;
229 namespaces = other.namespaces;
230 name = other.name;
231 value = other.value;
232 }
234 void findElementsRecursive(std::vector<Element *>&res, const DOMString &name);
236 void writeIndentedRecursive(FILE *f, int indent);
238 Element *parent;
240 std::vector<Element *>children;
242 std::vector<Attribute> attributes;
243 std::vector<Namespace> namespaces;
245 DOMString name;
246 DOMString value;
248 };
254 class Parser
255 {
256 public:
257 /**
258 * Constructor
259 */
260 Parser()
261 { init(); }
263 virtual ~Parser()
264 {}
266 /**
267 * Parse XML in a char buffer.
268 * @param buf a character buffer to parse
269 * @param pos position to start parsing
270 * @param len number of chars, from pos, to parse.
271 * @return a pointer to the root of the XML document;
272 */
273 Element *parse(const char *buf,int pos,int len);
275 /**
276 * Parse XML in a char buffer.
277 * @param buf a character buffer to parse
278 * @param pos position to start parsing
279 * @param len number of chars, from pos, to parse.
280 * @return a pointer to the root of the XML document;
281 */
282 Element *parse(const DOMString &buf);
284 /**
285 * Parse a named XML file. The file is loaded like a data file;
286 * the original format is not preserved.
287 * @param fileName the name of the file to read
288 * @return a pointer to the root of the XML document;
289 */
290 Element *parseFile(const DOMString &fileName);
292 /**
293 * Utility method to preprocess a string for XML
294 * output, escaping its entities.
295 * @param str the string to encode
296 */
297 static DOMString encode(const DOMString &str);
299 /**
300 * Removes whitespace from beginning and end of a string
301 */
302 DOMString trim(const DOMString &s);
304 private:
306 void init()
307 {
308 keepGoing = true;
309 currentNode = NULL;
310 parselen = 0;
311 parsebuf = NULL;
312 currentPosition = 0;
313 }
315 void getLineAndColumn(long pos, long *lineNr, long *colNr);
317 void error(char *fmt, ...) G_GNUC_PRINTF(2,3);
319 int peek(long pos);
321 int match(long pos, const char *text);
323 int skipwhite(long p);
325 int getWord(int p0, DOMString &buf);
327 int getQuoted(int p0, DOMString &buf, int do_i_parse);
329 int parseVersion(int p0);
331 int parseDoctype(int p0);
333 int parseElement(int p0, Element *par,int depth);
335 Element *parse(XMLCh *buf,int pos,int len);
337 bool keepGoing;
338 Element *currentNode;
339 long parselen;
340 XMLCh *parsebuf;
341 DOMString cdatabuf;
342 long currentPosition;
343 int colNr;
345 };
349 }//namespace Pedro
352 #endif /* __PEDRODOM_H__ */
354 //########################################################################
355 //# E N D O F F I L E
356 //########################################################################