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 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 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 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> 193 static void delete_object(T* obj) 194 { 195 delete obj; 196 } 197 198 #endif // XML_H 199