199 lines
6.4 KiB
C++
199 lines
6.4 KiB
C++
#ifndef XML_H
|
|
#define XML_H
|
|
|
|
#include "SourcePos.h"
|
|
|
|
#include <algorithm>
|
|
#include <string>
|
|
#include <vector>
|
|
#include <map>
|
|
|
|
#define XMLNS_XMLNS "http://www.w3.org/XML/1998/namespace"
|
|
|
|
using namespace std;
|
|
|
|
string trim_string(const string& str);
|
|
|
|
struct XMLAttribute
|
|
{
|
|
string ns;
|
|
string name;
|
|
string value;
|
|
|
|
XMLAttribute();
|
|
XMLAttribute(const XMLAttribute& that);
|
|
XMLAttribute(string ns, string name, string value);
|
|
~XMLAttribute();
|
|
|
|
int Compare(const XMLAttribute& that) const;
|
|
|
|
inline bool operator<(const XMLAttribute& that) const { return Compare(that) < 0; }
|
|
inline bool operator<=(const XMLAttribute& that) const { return Compare(that) <= 0; }
|
|
inline bool operator==(const XMLAttribute& that) const { return Compare(that) == 0; }
|
|
inline bool operator!=(const XMLAttribute& that) const { return Compare(that) != 0; }
|
|
inline bool operator>=(const XMLAttribute& that) const { return Compare(that) >= 0; }
|
|
inline bool operator>(const XMLAttribute& that) const { return Compare(that) > 0; }
|
|
|
|
static string Find(const vector<XMLAttribute>& list,
|
|
const string& ns, const string& name, const string& def);
|
|
};
|
|
|
|
class XMLNamespaceMap
|
|
{
|
|
public:
|
|
XMLNamespaceMap();
|
|
XMLNamespaceMap(char const*const* nspaces);
|
|
string Get(const string& ns) const;
|
|
string GetPrefix(const string& ns) const;
|
|
void AddToAttributes(vector<XMLAttribute>* attrs) const;
|
|
private:
|
|
map<string,string> m_map;
|
|
};
|
|
|
|
struct XMLNode
|
|
{
|
|
public:
|
|
enum {
|
|
EXACT = 0,
|
|
PRETTY = 1
|
|
};
|
|
|
|
enum {
|
|
ELEMENT = 0,
|
|
TEXT = 1
|
|
};
|
|
|
|
static XMLNode* NewElement(const SourcePos& pos, const string& ns, const string& name,
|
|
const vector<XMLAttribute>& attrs, int pretty);
|
|
static XMLNode* NewText(const SourcePos& pos, const string& text, int pretty);
|
|
|
|
~XMLNode();
|
|
|
|
// a deep copy
|
|
XMLNode* Clone() const;
|
|
|
|
inline int Type() const { return m_type; }
|
|
inline int Pretty() const { return m_pretty; }
|
|
void SetPrettyRecursive(int value);
|
|
string ContentsToString(const XMLNamespaceMap& nspaces) const;
|
|
string ToString(const XMLNamespaceMap& nspaces) const;
|
|
string OpenTagToString(const XMLNamespaceMap& nspaces, int pretty) const;
|
|
|
|
string CollapseTextContents() const;
|
|
|
|
inline const SourcePos& Position() const { return m_pos; }
|
|
|
|
// element
|
|
inline string Namespace() const { return m_ns; }
|
|
inline string Name() const { return m_name; }
|
|
inline void SetName(const string& ns, const string& n) { m_ns = ns; m_name = n; }
|
|
inline const vector<XMLAttribute>& Attributes() const { return m_attrs; }
|
|
inline vector<XMLAttribute>& EditAttributes() { return m_attrs; }
|
|
inline const vector<XMLNode*>& Children() const { return m_children; }
|
|
inline vector<XMLNode*>& EditChildren() { return m_children; }
|
|
vector<XMLNode*> GetElementsByName(const string& ns, const string& name) const;
|
|
XMLNode* GetElementByNameAt(const string& ns, const string& name, size_t index) const;
|
|
size_t CountElementsByName(const string& ns, const string& name) const;
|
|
string GetAttribute(const string& ns, const string& name, const string& def) const;
|
|
|
|
// text
|
|
inline string Text() const { return m_text; }
|
|
|
|
private:
|
|
XMLNode();
|
|
XMLNode(const XMLNode&);
|
|
|
|
string contents_to_string(const XMLNamespaceMap& nspaces, const string& indent) const;
|
|
string to_string(const XMLNamespaceMap& nspaces, const string& indent) const;
|
|
string open_tag_to_string(const XMLNamespaceMap& nspaces, const string& indent,
|
|
int pretty) const;
|
|
|
|
int m_type;
|
|
int m_pretty;
|
|
SourcePos m_pos;
|
|
|
|
// element
|
|
string m_ns;
|
|
string m_name;
|
|
vector<XMLAttribute> m_attrs;
|
|
vector<XMLNode*> m_children;
|
|
|
|
// text
|
|
string m_text;
|
|
};
|
|
|
|
class XMLHandler
|
|
{
|
|
public:
|
|
// information about the element that started us
|
|
SourcePos elementPos;
|
|
string elementNamespace;
|
|
string elementName;
|
|
vector<XMLAttribute> elementAttributes;
|
|
|
|
XMLHandler();
|
|
virtual ~XMLHandler();
|
|
|
|
XMLHandler* parent;
|
|
|
|
virtual int OnStartElement(const SourcePos& pos, const string& ns, const string& name,
|
|
const vector<XMLAttribute>& attrs, XMLHandler** next);
|
|
virtual int OnEndElement(const SourcePos& pos, const string& ns, const string& name);
|
|
virtual int OnText(const SourcePos& pos, const string& text);
|
|
virtual int OnComment(const SourcePos& pos, const string& text);
|
|
virtual int OnDone(const SourcePos& pos);
|
|
|
|
static bool ParseFile(const string& filename, XMLHandler* handler);
|
|
static bool ParseString(const string& filename, const string& text, XMLHandler* handler);
|
|
};
|
|
|
|
class TopElementHandler : public XMLHandler
|
|
{
|
|
public:
|
|
TopElementHandler(const string& ns, const string& name, XMLHandler* next);
|
|
|
|
virtual int OnStartElement(const SourcePos& pos, const string& ns, const string& name,
|
|
const vector<XMLAttribute>& attrs, XMLHandler** next);
|
|
virtual int OnEndElement(const SourcePos& pos, const string& ns, const string& name);
|
|
virtual int OnText(const SourcePos& pos, const string& text);
|
|
virtual int OnDone(const SourcePos& endPos);
|
|
|
|
private:
|
|
string m_ns;
|
|
string m_name;
|
|
XMLHandler* m_next;
|
|
};
|
|
|
|
class NodeHandler : public XMLHandler
|
|
{
|
|
public:
|
|
// after it's done, you own everything created and added to root
|
|
NodeHandler(XMLNode* root, int pretty);
|
|
~NodeHandler();
|
|
|
|
virtual int OnStartElement(const SourcePos& pos, const string& ns, const string& name,
|
|
const vector<XMLAttribute>& attrs, XMLHandler** next);
|
|
virtual int OnEndElement(const SourcePos& pos, const string& ns, const string& name);
|
|
virtual int OnText(const SourcePos& pos, const string& text);
|
|
virtual int OnComment(const SourcePos& pos, const string& text);
|
|
virtual int OnDone(const SourcePos& endPos);
|
|
|
|
inline XMLNode* Root() const { return m_root; }
|
|
|
|
static XMLNode* ParseFile(const string& filename, int pretty);
|
|
static XMLNode* ParseString(const string& filename, const string& text, int pretty);
|
|
|
|
private:
|
|
XMLNode* m_root;
|
|
int m_pretty;
|
|
vector<XMLNode*> m_nodes;
|
|
};
|
|
|
|
template <class T>
|
|
static void delete_object(T* obj)
|
|
{
|
|
delete obj;
|
|
}
|
|
|
|
#endif // XML_H
|