cc9a322f983f93842a5116daa69db3a67042cdea
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-2006 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 <string>
27 #include <vector>
30 namespace Pedro
31 {
33 typedef std::string DOMString;
34 typedef unsigned int XMLCh;
37 class Namespace
38 {
39 public:
40 Namespace()
41 {}
43 Namespace(const DOMString &prefixArg, const DOMString &namespaceURIArg)
44 {
45 prefix = prefixArg;
46 namespaceURI = namespaceURIArg;
47 }
49 Namespace(const Namespace &other)
50 {
51 assign(other);
52 }
54 Namespace &operator=(const Namespace &other)
55 {
56 assign(other);
57 return *this;
58 }
60 virtual ~Namespace()
61 {}
63 virtual DOMString getPrefix()
64 { return prefix; }
66 virtual DOMString getNamespaceURI()
67 { return namespaceURI; }
69 protected:
71 void assign(const Namespace &other)
72 {
73 prefix = other.prefix;
74 namespaceURI = other.namespaceURI;
75 }
77 DOMString prefix;
78 DOMString namespaceURI;
80 };
82 class Attribute
83 {
84 public:
85 Attribute()
86 {}
88 Attribute(const DOMString &nameArg, const DOMString &valueArg)
89 {
90 name = nameArg;
91 value = valueArg;
92 }
94 Attribute(const Attribute &other)
95 {
96 assign(other);
97 }
99 Attribute &operator=(const Attribute &other)
100 {
101 assign(other);
102 return *this;
103 }
105 virtual ~Attribute()
106 {}
108 virtual DOMString getName()
109 { return name; }
111 virtual DOMString getValue()
112 { return value; }
114 protected:
116 void assign(const Attribute &other)
117 {
118 name = other.name;
119 value = other.value;
120 }
122 DOMString name;
123 DOMString value;
125 };
128 class Element
129 {
130 friend class Parser;
132 public:
133 Element()
134 {
135 parent = NULL;
136 }
138 Element(const DOMString &nameArg)
139 {
140 parent = NULL;
141 name = nameArg;
142 }
144 Element(const DOMString &nameArg, const DOMString &valueArg)
145 {
146 parent = NULL;
147 name = nameArg;
148 value = valueArg;
149 }
151 Element(const Element &other)
152 {
153 assign(other);
154 }
156 Element &operator=(const Element &other)
157 {
158 assign(other);
159 return *this;
160 }
162 virtual Element *clone();
164 virtual ~Element()
165 {
166 for (unsigned int i=0 ; i<children.size() ; i++)
167 delete children[i];
168 }
170 virtual DOMString getName()
171 { return name; }
173 virtual DOMString getValue()
174 { return value; }
176 Element *getParent()
177 { return parent; }
179 Element *getFirstChild()
180 { return (children.size() == 0) ? NULL : children[0]; }
182 std::vector<Element *> getChildren()
183 { return children; }
185 std::vector<Element *> findElements(const DOMString &name);
187 DOMString getAttribute(const DOMString &name);
189 std::vector<Attribute> &getAttributes()
190 { return attributes; }
192 DOMString getTagAttribute(const DOMString &tagName, const DOMString &attrName);
194 DOMString getTagValue(const DOMString &tagName);
196 void addChild(Element *child);
198 void addAttribute(const DOMString &name, const DOMString &value);
200 void addNamespace(const DOMString &prefix, const DOMString &namespaceURI);
202 bool exists(const DOMString &name)
203 { return (findElements(name).size() > 0); }
205 /**
206 * Prettyprint an XML tree to an output stream. Elements are indented
207 * according to element hierarchy.
208 * @param f a stream to receive the output
209 * @param elem the element to output
210 */
211 void writeIndented(FILE *f);
213 /**
214 * Prettyprint an XML tree to standard output. This is the equivalent of
215 * writeIndented(stdout).
216 * @param elem the element to output
217 */
218 void print();
220 protected:
222 void assign(const Element &other)
223 {
224 parent = other.parent;
225 children = other.children;
226 attributes = other.attributes;
227 namespaces = other.namespaces;
228 name = other.name;
229 value = other.value;
230 }
232 void findElementsRecursive(std::vector<Element *>&res, const DOMString &name);
234 void writeIndentedRecursive(FILE *f, int indent);
236 Element *parent;
238 std::vector<Element *>children;
240 std::vector<Attribute> attributes;
241 std::vector<Namespace> namespaces;
243 DOMString name;
244 DOMString value;
246 };
252 class Parser
253 {
254 public:
255 /**
256 * Constructor
257 */
258 Parser()
259 { init(); }
261 virtual ~Parser()
262 {}
264 /**
265 * Parse XML in a char buffer.
266 * @param buf a character buffer to parse
267 * @param pos position to start parsing
268 * @param len number of chars, from pos, to parse.
269 * @return a pointer to the root of the XML document;
270 */
271 Element *parse(const char *buf,int pos,int len);
273 /**
274 * Parse XML in a char buffer.
275 * @param buf a character buffer to parse
276 * @param pos position to start parsing
277 * @param len number of chars, from pos, to parse.
278 * @return a pointer to the root of the XML document;
279 */
280 Element *parse(const DOMString &buf);
282 /**
283 * Parse a named XML file. The file is loaded like a data file;
284 * the original format is not preserved.
285 * @param fileName the name of the file to read
286 * @return a pointer to the root of the XML document;
287 */
288 Element *parseFile(const DOMString &fileName);
290 /**
291 * Utility method to preprocess a string for XML
292 * output, escaping its entities.
293 * @param str the string to encode
294 */
295 static DOMString encode(const DOMString &str);
297 /**
298 * Removes whitespace from beginning and end of a string
299 */
300 DOMString trim(const DOMString &s);
302 private:
304 void init()
305 {
306 keepGoing = true;
307 currentNode = NULL;
308 parselen = 0;
309 parsebuf = NULL;
310 currentPosition = 0;
311 }
313 void getLineAndColumn(long pos, long *lineNr, long *colNr);
315 void error(char *fmt, ...);
317 int peek(long pos);
319 int match(long pos, const char *text);
321 int skipwhite(long p);
323 int getWord(int p0, DOMString &buf);
325 int getQuoted(int p0, DOMString &buf, int do_i_parse);
327 int parseVersion(int p0);
329 int parseDoctype(int p0);
331 int parseElement(int p0, Element *par,int depth);
333 Element *parse(XMLCh *buf,int pos,int len);
335 bool keepGoing;
336 Element *currentNode;
337 long parselen;
338 XMLCh *parsebuf;
339 DOMString cdatabuf;
340 long currentPosition;
341 int colNr;
343 };
347 }//namespace Pedro
350 #endif /* __PEDRODOM_H__ */
352 //########################################################################
353 //# E N D O F F I L E
354 //########################################################################