• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef XML_H
2 #define XML_H
3 
4 #include "SourcePos.h"
5 
6 #include <algorithm>
7 #include <string>
8 #include <vector>
9 #include <map>
10 
11 #define XMLNS_XMLNS "http://www.w3.org/XML/1998/namespace"
12 
13 using namespace std;
14 
15 string trim_string(const string& str);
16 
17 struct XMLAttribute
18 {
19     string ns;
20     string name;
21     string value;
22 
23     XMLAttribute();
24     XMLAttribute(const XMLAttribute& that);
25     XMLAttribute(string ns, string name, string value);
26     ~XMLAttribute();
27 
28     int Compare(const XMLAttribute& that) const;
29 
30     inline bool operator<(const XMLAttribute& that) const { return Compare(that) < 0; }
31     inline bool operator<=(const XMLAttribute& that) const { return Compare(that) <= 0; }
32     inline bool operator==(const XMLAttribute& that) const { return Compare(that) == 0; }
33     inline bool operator!=(const XMLAttribute& that) const { return Compare(that) != 0; }
34     inline bool operator>=(const XMLAttribute& that) const { return Compare(that) >= 0; }
35     inline bool operator>(const XMLAttribute& that) const { return Compare(that) > 0; }
36 
37     static string Find(const vector<XMLAttribute>& list,
38                                 const string& ns, const string& name, const string& def);
39 };
40 
41 class XMLNamespaceMap
42 {
43 public:
44     XMLNamespaceMap();
45     XMLNamespaceMap(char const*const* nspaces);
46     string Get(const string& ns) const;
47     string GetPrefix(const string& ns) const;
48     void AddToAttributes(vector<XMLAttribute>* attrs) const;
49 private:
50     map<string,string> m_map;
51 };
52 
53 struct XMLNode
54 {
55 public:
56     enum {
57         EXACT = 0,
58         PRETTY = 1
59     };
60 
61     enum {
62         ELEMENT = 0,
63         TEXT = 1
64     };
65 
66     static XMLNode* NewElement(const SourcePos& pos, const string& ns, const string& name,
67                         const vector<XMLAttribute>& attrs, int pretty);
68     static XMLNode* NewText(const SourcePos& pos, const string& text, int pretty);
69 
70     ~XMLNode();
71 
72     // a deep copy
73     XMLNode* Clone() const;
74 
TypeXMLNode75     inline int Type() const                                     { return m_type; }
PrettyXMLNode76     inline int Pretty() const                                   { return m_pretty; }
77     void SetPrettyRecursive(int value);
78     string ContentsToString(const XMLNamespaceMap& nspaces) const;
79     string ToString(const XMLNamespaceMap& nspaces) const;
80     string OpenTagToString(const XMLNamespaceMap& nspaces, int pretty) const;
81 
82     string CollapseTextContents() const;
83 
PositionXMLNode84     inline const SourcePos& Position() const                    { return m_pos; }
85 
86     // element
NamespaceXMLNode87     inline string Namespace() const                             { return m_ns; }
NameXMLNode88     inline string Name() const                                  { return m_name; }
SetNameXMLNode89     inline void SetName(const string& ns, const string& n)      { m_ns = ns; m_name = n; }
AttributesXMLNode90     inline const vector<XMLAttribute>& Attributes() const       { return m_attrs; }
EditAttributesXMLNode91     inline vector<XMLAttribute>& EditAttributes()               { return m_attrs; }
ChildrenXMLNode92     inline const vector<XMLNode*>& Children() const             { return m_children; }
EditChildrenXMLNode93     inline vector<XMLNode*>& EditChildren()                     { return m_children; }
94     vector<XMLNode*> GetElementsByName(const string& ns, const string& name) const;
95     XMLNode* GetElementByNameAt(const string& ns, const string& name, size_t index) const;
96     size_t CountElementsByName(const string& ns, const string& name) const;
97     string GetAttribute(const string& ns, const string& name, const string& def) const;
98 
99     // text
TextXMLNode100     inline string Text() const                                  { return m_text; }
101 
102 private:
103     XMLNode();
104     XMLNode(const XMLNode&);
105 
106     string contents_to_string(const XMLNamespaceMap& nspaces, const string& indent) const;
107     string to_string(const XMLNamespaceMap& nspaces, const string& indent) const;
108     string open_tag_to_string(const XMLNamespaceMap& nspaces, const string& indent,
109             int pretty) const;
110 
111     int m_type;
112     int m_pretty;
113     SourcePos m_pos;
114 
115     // element
116     string m_ns;
117     string m_name;
118     vector<XMLAttribute> m_attrs;
119     vector<XMLNode*> m_children;
120 
121     // text
122     string m_text;
123 };
124 
125 class XMLHandler
126 {
127 public:
128     // information about the element that started us
129     SourcePos elementPos;
130     string elementNamespace;
131     string elementName;
132     vector<XMLAttribute> elementAttributes;
133 
134     XMLHandler();
135     virtual ~XMLHandler();
136 
137     XMLHandler* parent;
138 
139     virtual int OnStartElement(const SourcePos& pos, const string& ns, const string& name,
140                                 const vector<XMLAttribute>& attrs, XMLHandler** next);
141     virtual int OnEndElement(const SourcePos& pos, const string& ns, const string& name);
142     virtual int OnText(const SourcePos& pos, const string& text);
143     virtual int OnComment(const SourcePos& pos, const string& text);
144     virtual int OnDone(const SourcePos& pos);
145 
146     static bool ParseFile(const string& filename, XMLHandler* handler);
147     static bool ParseString(const string& filename, const string& text, XMLHandler* handler);
148 };
149 
150 class TopElementHandler : public XMLHandler
151 {
152 public:
153     TopElementHandler(const string& ns, const string& name, XMLHandler* next);
154 
155     virtual int OnStartElement(const SourcePos& pos, const string& ns, const string& name,
156                                 const vector<XMLAttribute>& attrs, XMLHandler** next);
157     virtual int OnEndElement(const SourcePos& pos, const string& ns, const string& name);
158     virtual int OnText(const SourcePos& pos, const string& text);
159     virtual int OnDone(const SourcePos& endPos);
160 
161 private:
162     string m_ns;
163     string m_name;
164     XMLHandler* m_next;
165 };
166 
167 class NodeHandler : public XMLHandler
168 {
169 public:
170     // after it's done, you own everything created and added to root
171     NodeHandler(XMLNode* root, int pretty);
172     ~NodeHandler();
173 
174     virtual int OnStartElement(const SourcePos& pos, const string& ns, const string& name,
175                                 const vector<XMLAttribute>& attrs, XMLHandler** next);
176     virtual int OnEndElement(const SourcePos& pos, const string& ns, const string& name);
177     virtual int OnText(const SourcePos& pos, const string& text);
178     virtual int OnComment(const SourcePos& pos, const string& text);
179     virtual int OnDone(const SourcePos& endPos);
180 
Root()181     inline XMLNode* Root() const                { return m_root; }
182 
183     static XMLNode* ParseFile(const string& filename, int pretty);
184     static XMLNode* ParseString(const string& filename, const string& text, int pretty);
185 
186 private:
187     XMLNode* m_root;
188     int m_pretty;
189     vector<XMLNode*> m_nodes;
190 };
191 
192 template <class T>
delete_object(T * obj)193 static void delete_object(T* obj)
194 {
195     delete obj;
196 }
197 
198 #endif // XML_H
199