/*************************************************************************** * Copyright (C) 2005 by Christof Donat * * cdonat@gmx.de * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program 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 General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #ifndef HSADMIN_XMLPARSER #define HSADMIN_XMLPARSER /** \brief a general XML Parser * * well, it works for me. The API is inspired a bit by SAX, but I didn't * whant to create the full SAX API. */ namespace xmlParser { using std::string; using std::map; using std::vector; //! Node Types typedef enum { UNKNOWN = 0, ELEMENT = 1, ATTRIBUTE = 2, TEXT = 3, CDATA = 4, PROCESSING_INSTRUCTION = 7, COMMENT = 8, DOCUMENT = 9, } nodeType; //! base class for all Nodes class Node { public: Node(nodeType type): m_type(type) {}; Node(): m_type(UNKNOWN) {}; nodeType m_type; }; //! Text node class Text: public Node { public: Text(): m_content(""), Node::Node(TEXT) {}; //! create a Text node from a C++ String Text(string content): m_content(content), Node::Node(TEXT) {}; //! copy-construct a Text node Text(const Text &text): m_content(text.m_content), Node::Node(TEXT) {}; //! the actual text string m_content; }; //! Element node class Element: public Node { public: Element(): m_nodes(vector(0)), m_attributes(map()), m_name(""), Node::Node(ELEMENT) {}; //! create a Element from its tag-name , a List of Attributes and a List of Child-Nodes Element(string name, map attributes, vector content): m_nodes(content), m_attributes(attributes), m_name(name), Node::Node(ELEMENT) {}; //! copy-construct a Element Node Element(const Element &elm): m_nodes(elm.m_nodes), m_attributes(elm.m_attributes), m_name(elm.m_name), Node::Node(ELEMENT) {}; //! The tag name string m_name; //! the attributes map m_attributes; //! che child nodes vector m_nodes; }; //! the XML parser calls the operator() for everything it finds class responseParserHook { public: enum { ELEMENT = 1, ATTRIBUTE = 2, TEXT = 3, CDATA = 4, PROCESSING_INSTRUCTION = 7, COMMENT = 8, DOCUMENT = 9, START_ELEMENT = 16, END_ELEMENT = 17, EMPTY_ELEMENT = 18, ATTRIBUTE_VALUE = 32, }; virtual bool operator()(int type, string content) = 0; }; //! a dummy Parser; the general parser base class class parser { public: bool operator()(const string& content, int &pos, responseParserHook *hook); }; /** \brief Template to construct a Parser from two parsers. * * combines the results of the two parsers with 'or'. */ template class orRule : public parser { public: inline bool operator()(const string& content, int &pos, responseParserHook *hook) { int oldpos = pos; if( !car(content,pos,hook) ) return cdr(content,pos,hook); return true; }; private: first car; second cdr; }; //! parse everything that is a space class spaceParser: public parser { public: bool operator()(const string& content, int &pos, responseParserHook *hook); }; //! parse XML comments class commentParser { public: bool operator()(const string& content, int &pos, responseParserHook *hook); }; //! parse either spaces or comments typedef orRule comspaceParser; //! parse XML names class nameParser: public parser { public: bool operator()(const string& content, int &pos, responseParserHook *hook); }; //! parse XML attribute values class attributeValueParser: public parser { public: bool operator()(const string& content, int &pos, responseParserHook *hook); }; //! parse XML attributes with name and value class attributeParser: public parser { public: bool operator()(const string& content, int &pos, responseParserHook *hook); private: nameParser name; spaceParser space; attributeValueParser value; }; //! parse an empty element class emptyelemParser: public parser { public: bool operator()(const string& content, int &pos, responseParserHook *hook); private: nameParser name; attributeParser attrib; spaceParser space; }; //! parse the start of an element class startelemParser: public parser { public: bool operator()(const string& content, int &pos, responseParserHook *hook); private: nameParser name; attributeParser attrib; spaceParser space; }; //! parse the end of an element class endelemParser: public parser { public: bool operator()(const string& content, int &pos, responseParserHook *hook); private: nameParser name; spaceParser space; }; //! parse Text class textParser: public parser { public: bool operator()(const string& content, int &pos, responseParserHook *hook); }; //! parse CDATA-sections class cdataParser: public parser { public: bool operator()(const string& content, int &pos, responseParserHook *hook); }; //! parse general Elements class elemParser: public parser { public: bool operator()(const string& content, int &pos, responseParserHook *hook); private: emptyelemParser emptyelem; startelemParser elemstart; comspaceParser comspace; endelemParser endelem; textParser text; cdataParser cdata; }; //! parse the xml Processing instruction at the beginning of each XML-File class xmlpcParser: public parser { public: bool operator()(const string& content, int &pos, responseParserHook *hook); private: nameParser name; attributeParser attrib; spaceParser space; }; //! parse an XML-File class XMLParser: public parser { public: bool operator()(const string& content, int &pos, responseParserHook *hook); private: spaceParser space; xmlpcParser xmlpc; comspaceParser comspace; elemParser elem; }; //! just a convenient wraper around the XMLParser class ResponseParser { public: bool operator()(const string& content, responseParserHook *hook); private: XMLParser xml; }; } #else /* HSADMIN_XMLPARSER */ namespace xmlParser { class responseParserHook; class parser; template class orRule; class spaceParser; class commentParser; class nameParser; class attributeValueParser; class attributeParser; class emptyelemParser; class startelemParser; class endelemParser; class textParser; class cdataParser; class elemParser; class xmlpcParser; class XMLParser; class ResponseParser; } #endif /* HSADMIN_XMLPARSER */