c64ab570a1
work. please note, that I would do quite some things differently nowadays. I home to get those things in via refactoring
297 lines
7.5 KiB
C++
297 lines
7.5 KiB
C++
/***************************************************************************
|
|
* 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 <string>
|
|
#include <map>
|
|
#include <vector>
|
|
|
|
#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<Node*>(0)),
|
|
m_attributes(map<string,string>()),
|
|
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<string,string> attributes, vector<Node*> 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<string,string> m_attributes;
|
|
//! che child nodes
|
|
vector<Node*> 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 first, class second> 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<spaceParser, commentParser> 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 first, class second> 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 */
|