blob: 324385fcc2db1c8091766b16c4118380e674a971 [file] [log] [blame]
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -07001#ifndef XML_H
2#define XML_H
3
4#include "SourcePos.h"
5
Alexey Zaytsev862bfdb2008-10-22 02:05:55 +04006#include <algorithm>
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -07007#include <string>
8#include <vector>
9#include <map>
10
11#define XMLNS_XMLNS "http://www.w3.org/XML/1998/namespace"
12
13using namespace std;
14
15string trim_string(const string& str);
16
17struct 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
41class XMLNamespaceMap
42{
43public:
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;
49private:
50 map<string,string> m_map;
51};
52
53struct XMLNode
54{
55public:
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
75 inline int Type() const { return m_type; }
76 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
84 inline const SourcePos& Position() const { return m_pos; }
85
86 // element
87 inline string Namespace() const { return m_ns; }
88 inline string Name() const { return m_name; }
89 inline void SetName(const string& ns, const string& n) { m_ns = ns; m_name = n; }
90 inline const vector<XMLAttribute>& Attributes() const { return m_attrs; }
91 inline vector<XMLAttribute>& EditAttributes() { return m_attrs; }
92 inline const vector<XMLNode*>& Children() const { return m_children; }
93 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
100 inline string Text() const { return m_text; }
101
102private:
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
125class XMLHandler
126{
127public:
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
150class TopElementHandler : public XMLHandler
151{
152public:
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
161private:
162 string m_ns;
163 string m_name;
164 XMLHandler* m_next;
165};
166
167class NodeHandler : public XMLHandler
168{
169public:
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
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
186private:
187 XMLNode* m_root;
188 int m_pretty;
189 vector<XMLNode*> m_nodes;
190};
191
192template <class T>
193static void delete_object(T* obj)
194{
195 delete obj;
196}
197
198#endif // XML_H