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