hs.hsadmin/hsacppcli/hsadminc/source/xmlparser.h

297 lines
7.5 KiB
C
Raw Normal View History

/***************************************************************************
* 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 */