#ifndef __PEDRODOM_H__ #define __PEDRODOM_H__ /* * API for the Pedro mini-DOM parser and tree * * Authors: * Bob Jamison * * Copyright (C) 2005-2006 Bob Jamison * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include namespace Pedro { typedef std::string DOMString; typedef unsigned int XMLCh; class Namespace { public: Namespace() {} Namespace(const DOMString &prefixArg, const DOMString &namespaceURIArg) { prefix = prefixArg; namespaceURI = namespaceURIArg; } Namespace(const Namespace &other) { assign(other); } Namespace &operator=(const Namespace &other) { assign(other); return *this; } virtual ~Namespace() {} virtual DOMString getPrefix() { return prefix; } virtual DOMString getNamespaceURI() { return namespaceURI; } protected: void assign(const Namespace &other) { prefix = other.prefix; namespaceURI = other.namespaceURI; } DOMString prefix; DOMString namespaceURI; }; class Attribute { public: Attribute() {} Attribute(const DOMString &nameArg, const DOMString &valueArg) { name = nameArg; value = valueArg; } Attribute(const Attribute &other) { assign(other); } Attribute &operator=(const Attribute &other) { assign(other); return *this; } virtual ~Attribute() {} virtual DOMString getName() { return name; } virtual DOMString getValue() { return value; } protected: void assign(const Attribute &other) { name = other.name; value = other.value; } DOMString name; DOMString value; }; class Element { friend class Parser; public: Element() { parent = NULL; } Element(const DOMString &nameArg) { parent = NULL; name = nameArg; } Element(const DOMString &nameArg, const DOMString &valueArg) { parent = NULL; name = nameArg; value = valueArg; } Element(const Element &other) { assign(other); } Element &operator=(const Element &other) { assign(other); return *this; } virtual Element *clone(); virtual ~Element() { for (unsigned int i=0 ; i getChildren() { return children; } std::vector findElements(const DOMString &name); DOMString getAttribute(const DOMString &name); std::vector &getAttributes() { return attributes; } DOMString getTagAttribute(const DOMString &tagName, const DOMString &attrName); DOMString getTagValue(const DOMString &tagName); void addChild(Element *child); void addAttribute(const DOMString &name, const DOMString &value); void addNamespace(const DOMString &prefix, const DOMString &namespaceURI); bool exists(const DOMString &name) { return (findElements(name).size() > 0); } /** * Prettyprint an XML tree to an output stream. Elements are indented * according to element hierarchy. * @param f a stream to receive the output * @param elem the element to output */ void writeIndented(FILE *f); /** * Prettyprint an XML tree to standard output. This is the equivalent of * writeIndented(stdout). * @param elem the element to output */ void print(); protected: void assign(const Element &other) { parent = other.parent; children = other.children; attributes = other.attributes; namespaces = other.namespaces; name = other.name; value = other.value; } void findElementsRecursive(std::vector&res, const DOMString &name); void writeIndentedRecursive(FILE *f, int indent); Element *parent; std::vectorchildren; std::vector attributes; std::vector namespaces; DOMString name; DOMString value; }; class Parser { public: /** * Constructor */ Parser() { init(); } virtual ~Parser() {} /** * Parse XML in a char buffer. * @param buf a character buffer to parse * @param pos position to start parsing * @param len number of chars, from pos, to parse. * @return a pointer to the root of the XML document; */ Element *parse(const char *buf,int pos,int len); /** * Parse XML in a char buffer. * @param buf a character buffer to parse * @param pos position to start parsing * @param len number of chars, from pos, to parse. * @return a pointer to the root of the XML document; */ Element *parse(const DOMString &buf); /** * Parse a named XML file. The file is loaded like a data file; * the original format is not preserved. * @param fileName the name of the file to read * @return a pointer to the root of the XML document; */ Element *parseFile(const DOMString &fileName); /** * Utility method to preprocess a string for XML * output, escaping its entities. * @param str the string to encode */ static DOMString encode(const DOMString &str); /** * Removes whitespace from beginning and end of a string */ DOMString trim(const DOMString &s); private: void init() { keepGoing = true; currentNode = NULL; parselen = 0; parsebuf = NULL; currentPosition = 0; } void getLineAndColumn(long pos, long *lineNr, long *colNr); void error(char *fmt, ...); int peek(long pos); int match(long pos, const char *text); int skipwhite(long p); int getWord(int p0, DOMString &buf); int getQuoted(int p0, DOMString &buf, int do_i_parse); int parseVersion(int p0); int parseDoctype(int p0); int parseElement(int p0, Element *par,int depth); Element *parse(XMLCh *buf,int pos,int len); bool keepGoing; Element *currentNode; long parselen; XMLCh *parsebuf; DOMString cdatabuf; long currentPosition; int colNr; }; }//namespace Pedro #endif /* __PEDRODOM_H__ */ //######################################################################## //# E N D O F F I L E //########################################################################