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 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 {
32 typedef std::string DOMString;
33 typedef unsigned int XMLCh;
36 class Namespace
37 {
38 public:
39 Namespace()
40 {}
42 Namespace(const DOMString &prefixArg, const DOMString &namespaceURIArg)
43 {
44 prefix = prefixArg;
45 namespaceURI = namespaceURIArg;
46 }
48 Namespace(const Namespace &other)
49 {
50 prefix = other.prefix;
51 namespaceURI = other.namespaceURI;
52 }
54 virtual ~Namespace()
55 {}
57 virtual DOMString getPrefix()
58 { return prefix; }
60 virtual DOMString getNamespaceURI()
61 { return namespaceURI; }
63 protected:
65 DOMString prefix;
66 DOMString namespaceURI;
68 };
70 class Attribute
71 {
72 public:
73 Attribute()
74 {}
76 Attribute(const DOMString &nameArg, const DOMString &valueArg)
77 {
78 name = nameArg;
79 value = valueArg;
80 }
82 Attribute(const Attribute &other)
83 {
84 name = other.name;
85 value = other.value;
86 }
88 virtual ~Attribute()
89 {}
91 virtual DOMString getName()
92 { return name; }
94 virtual DOMString getValue()
95 { return value; }
97 protected:
99 DOMString name;
100 DOMString value;
102 };
105 class Element
106 {
107 friend class Parser;
109 public:
110 Element()
111 {
112 parent = NULL;
113 }
115 Element(const DOMString &nameArg)
116 {
117 parent = NULL;
118 name = nameArg;
119 }
121 Element(const DOMString &nameArg, const DOMString &valueArg)
122 {
123 parent = NULL;
124 name = nameArg;
125 value = valueArg;
126 }
128 Element(const Element &other)
129 {
130 parent = other.parent;
131 children = other.children;
132 attributes = other.attributes;
133 namespaces = other.namespaces;
134 name = other.name;
135 value = other.value;
136 }
138 virtual Element *clone();
140 virtual ~Element()
141 {
142 for (unsigned int i=0 ; i<children.size() ; i++)
143 delete children[i];
144 }
146 virtual DOMString getName()
147 { return name; }
149 virtual DOMString getValue()
150 { return value; }
152 Element *getParent()
153 { return parent; }
155 std::vector<Element *> getChildren()
156 { return children; }
158 std::vector<Element *> findElements(const DOMString &name);
160 DOMString getAttribute(const DOMString &name);
162 DOMString getTagAttribute(const DOMString &tagName, const DOMString &attrName);
164 DOMString getTagValue(const DOMString &tagName);
166 void addChild(Element *child);
168 void addAttribute(const DOMString &name, const DOMString &value);
170 void addNamespace(const DOMString &prefix, const DOMString &namespaceURI);
173 /**
174 * Prettyprint an XML tree to an output stream. Elements are indented
175 * according to element hierarchy.
176 * @param f a stream to receive the output
177 * @param elem the element to output
178 */
179 void writeIndented(FILE *f);
181 /**
182 * Prettyprint an XML tree to standard output. This is the equivalent of
183 * writeIndented(stdout).
184 * @param elem the element to output
185 */
186 void print();
188 protected:
191 void findElementsRecursive(std::vector<Element *>&res, const DOMString &name);
193 void writeIndentedRecursive(FILE *f, int indent);
195 Element *parent;
197 std::vector<Element *>children;
199 std::vector<Attribute> attributes;
200 std::vector<Namespace> namespaces;
202 DOMString name;
203 DOMString value;
205 };
211 class Parser
212 {
213 public:
214 Parser()
215 { init(); }
217 virtual ~Parser()
218 {}
220 /**
221 * Parse XML in a char buffer.
222 * @param buf a character buffer to parse
223 * @param pos position to start parsing
224 * @param len number of chars, from pos, to parse.
225 * @return a pointer to the root of the XML document;
226 */
227 Element *parse(const char *buf,int pos,int len);
229 /**
230 * Parse XML in a char buffer.
231 * @param buf a character buffer to parse
232 * @param pos position to start parsing
233 * @param len number of chars, from pos, to parse.
234 * @return a pointer to the root of the XML document;
235 */
236 Element *parse(const DOMString &buf);
238 /**
239 * Parse a named XML file. The file is loaded like a data file;
240 * the original format is not preserved.
241 * @param fileName the name of the file to read
242 * @return a pointer to the root of the XML document;
243 */
244 Element *parseFile(const char *fileName);
246 /**
247 * Utility method to preprocess a string for XML
248 * output, escaping its entities.
249 * @param str the string to encode
250 */
251 static DOMString encode(const DOMString &str);
254 private:
256 void init()
257 {
258 keepGoing = true;
259 currentNode = NULL;
260 parselen = 0;
261 parsebuf = NULL;
262 currentPosition = 0;
263 }
265 void getLineAndColumn(long pos, long *lineNr, long *colNr);
267 void error(char *fmt, ...);
269 int peek(long pos);
271 int match(long pos, const char *text);
273 int skipwhite(long p);
275 int getWord(int p0, DOMString &buf);
277 int getQuoted(int p0, DOMString &buf, int do_i_parse);
279 int parseVersion(int p0);
281 int parseDoctype(int p0);
283 int parseElement(int p0, Element *par,int depth);
285 Element *parse(XMLCh *buf,int pos,int len);
287 bool keepGoing;
288 Element *currentNode;
289 long parselen;
290 XMLCh *parsebuf;
291 DOMString cdatabuf;
292 long currentPosition;
293 int colNr;
296 };
300 }//namespace Pedro
303 #endif /* __PEDRODOM_H__ */
305 //########################################################################
306 //# E N D O F F I L E
307 //########################################################################