1 /***************************************************************** 2 | 3 | Neptune - Xml Support 4 | 5 | Copyright (c) 2002-2008, Axiomatic Systems, LLC. 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | * Redistributions of source code must retain the above copyright 11 | notice, this list of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | * Neither the name of Axiomatic Systems nor the 16 | names of its contributors may be used to endorse or promote products 17 | derived from this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY 20 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY 23 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 ****************************************************************/ 31 32 #ifndef _NPT_XML_H_ 33 #define _NPT_XML_H_ 34 35 /*---------------------------------------------------------------------- 36 | includes 37 +---------------------------------------------------------------------*/ 38 #include "NptTypes.h" 39 #include "NptList.h" 40 #include "NptStrings.h" 41 #include "NptStreams.h" 42 43 /*---------------------------------------------------------------------- 44 | constants 45 +---------------------------------------------------------------------*/ 46 const int NPT_ERROR_XML_INVALID_NESTING = NPT_ERROR_BASE_XML - 0; 47 const int NPT_ERROR_XML_TAG_MISMATCH = NPT_ERROR_BASE_XML - 1; 48 const int NPT_ERROR_XML_NO_ROOT = NPT_ERROR_BASE_XML - 2; 49 const int NPT_ERROR_XML_MULTIPLE_ROOTS = NPT_ERROR_BASE_XML - 3; 50 51 #define NPT_XML_ANY_NAMESPACE "*" 52 #define NPT_XML_NO_NAMESPACE NULL 53 54 /*---------------------------------------------------------------------- 55 | forward declarations 56 +---------------------------------------------------------------------*/ 57 class NPT_XmlProcessor; 58 59 /*---------------------------------------------------------------------- 60 | NPT_XmlAttribute 61 +---------------------------------------------------------------------*/ 62 class NPT_XmlAttribute 63 { 64 public: 65 // methods 66 NPT_XmlAttribute(const char* name, const char* value); NPT_XmlAttribute(const char * prefix,const char * name,const char * value)67 NPT_XmlAttribute(const char* prefix, const char* name, const char* value) : 68 m_Prefix(prefix), m_Name(name), m_Value(value) {} GetPrefix()69 const NPT_String& GetPrefix() const { return m_Prefix; } GetName()70 const NPT_String& GetName() const { return m_Name; } GetValue()71 const NPT_String& GetValue() const { return m_Value; } SetValue(const char * value)72 void SetValue(const char* value) { m_Value = value; } 73 74 private: 75 // members 76 NPT_String m_Prefix; 77 NPT_String m_Name; 78 NPT_String m_Value; 79 NPT_XmlAttribute(const NPT_XmlAttribute & attribute)80 NPT_XmlAttribute(const NPT_XmlAttribute& attribute) : 81 m_Prefix(attribute.m_Prefix), 82 m_Name(attribute.m_Name), 83 m_Value(attribute.m_Value) {} 84 NPT_XmlAttribute& operator=(const NPT_XmlAttribute& a); 85 86 // friends 87 friend class NPT_XmlAttributeFinder; 88 friend class NPT_XmlAttributeFinderWithPrefix; 89 }; 90 91 /*---------------------------------------------------------------------- 92 | NPT_XmlNamespaceMap 93 +---------------------------------------------------------------------*/ 94 class NPT_XmlNamespaceMap 95 { 96 public: 97 // destructor 98 ~NPT_XmlNamespaceMap(); 99 100 // methods 101 NPT_Result SetNamespaceUri(const char* prefix, const char* uri); 102 const NPT_String* GetNamespaceUri(const char* prefix); 103 const NPT_String* GetNamespacePrefix(const char* uri); 104 105 private: 106 // types 107 class Entry { 108 public: 109 // constructor Entry(const char * prefix,const char * uri)110 Entry(const char* prefix, const char* uri) : 111 m_Prefix(prefix), m_Uri(uri) {} 112 113 // members 114 NPT_String m_Prefix; 115 NPT_String m_Uri; 116 }; 117 118 // members 119 NPT_List<Entry*> m_Entries; 120 121 // friends 122 friend class NPT_XmlWriter; 123 friend class NPT_XmlNodeWriter; 124 friend class NPT_XmlNodeCanonicalWriter; 125 }; 126 127 /*---------------------------------------------------------------------- 128 | NPT_XmlNode 129 +---------------------------------------------------------------------*/ 130 class NPT_XmlElementNode; 131 class NPT_XmlTextNode; 132 class NPT_XmlNode 133 { 134 public: 135 // types 136 typedef enum { 137 DOCUMENT, 138 ELEMENT, 139 TEXT 140 } Type; 141 142 // methods NPT_XmlNode(Type type)143 NPT_XmlNode(Type type) : m_Type(type), m_Parent(NULL) {} ~NPT_XmlNode()144 virtual ~NPT_XmlNode() {} GetType()145 Type GetType() const { return m_Type; } GetParent()146 NPT_XmlNode* GetParent() const { return m_Parent; } 147 148 // type casting AsElementNode()149 virtual NPT_XmlElementNode* AsElementNode() { return NULL; } AsElementNode()150 virtual const NPT_XmlElementNode* AsElementNode() const { return NULL; } AsTextNode()151 virtual NPT_XmlTextNode* AsTextNode() { return NULL; } AsTextNode()152 virtual const NPT_XmlTextNode* AsTextNode() const { return NULL; } 153 154 protected: 155 // methods SetParent(NPT_XmlNode * parent)156 virtual void SetParent(NPT_XmlNode* parent) { m_Parent = parent; } 157 158 // members 159 Type m_Type; 160 NPT_XmlNode* m_Parent; 161 162 // friends 163 friend class NPT_XmlNodeFinder; 164 friend class NPT_XmlSerializer; 165 friend class NPT_XmlWriter; 166 friend class NPT_XmlElementNode; // to allow access to SetParent() 167 }; 168 169 /*---------------------------------------------------------------------- 170 | NPT_XmlElementNode 171 +---------------------------------------------------------------------*/ 172 class NPT_XmlElementNode : public NPT_XmlNode 173 { 174 public: 175 // methods 176 NPT_XmlElementNode(const char* tag); 177 NPT_XmlElementNode(const char* prefix, const char* tag); 178 virtual ~NPT_XmlElementNode(); GetChildren()179 NPT_List<NPT_XmlNode*>& GetChildren() { return m_Children; } 180 const NPT_List<NPT_XmlNode*>& GetChildren()181 GetChildren() const { return m_Children; } 182 NPT_XmlElementNode* GetChild(const char* tag, 183 const char* namespc = NPT_XML_NO_NAMESPACE, 184 NPT_Ordinal n=0) const; 185 NPT_Result AddChild(NPT_XmlNode* child); 186 NPT_Result SetAttribute(const char* prefix, 187 const char* name, 188 const char* value); 189 NPT_Result SetAttribute(const char* name, 190 const char* value); 191 NPT_Result AddText(const char* text); 192 NPT_List<NPT_XmlAttribute*>& GetAttributes()193 GetAttributes() { return m_Attributes; } 194 const NPT_List<NPT_XmlAttribute*>& GetAttributes()195 GetAttributes() const { return m_Attributes; } 196 const NPT_String* GetAttribute(const char* name, 197 const char* namespc = NPT_XML_NO_NAMESPACE) const; GetPrefix()198 const NPT_String& GetPrefix() const { return m_Prefix; } GetTag()199 const NPT_String& GetTag() const { return m_Tag; } 200 const NPT_String* GetText(NPT_Ordinal n=0) const; 201 202 // bring all the namespace definitions used in this element of one of its descendants 203 // into the namespace map of this element so that it may be serialized as a 204 // standalone element without any prefixes with undefined namespace uris 205 NPT_Result MakeStandalone(); 206 207 // namespace methods 208 const NPT_String* GetNamespace() const; 209 NPT_Result SetNamespaceUri(const char* prefix, const char* uri); 210 const NPT_String* GetNamespaceUri(const char* prefix) const; 211 const NPT_String* GetNamespacePrefix(const char* uri) const; 212 213 // type casting AsElementNode()214 NPT_XmlElementNode* AsElementNode() { return this; } AsElementNode()215 const NPT_XmlElementNode* AsElementNode() const { return this; } 216 217 protected: 218 // methods 219 void SetParent(NPT_XmlNode* parent); 220 void SetNamespaceParent(NPT_XmlElementNode* parent); 221 void RelinkNamespaceMaps(); 222 223 NPT_Result AddAttribute(const char* name, const char* value); 224 225 // members 226 NPT_String m_Prefix; 227 NPT_String m_Tag; 228 NPT_List<NPT_XmlNode*> m_Children; 229 NPT_List<NPT_XmlAttribute*> m_Attributes; 230 NPT_XmlNamespaceMap* m_NamespaceMap; 231 NPT_XmlElementNode* m_NamespaceParent; 232 233 // friends 234 friend class NPT_XmlTagFinder; 235 friend class NPT_XmlSerializer; 236 friend class NPT_XmlWriter; 237 friend class NPT_XmlNodeWriter; 238 friend class NPT_XmlNodeCanonicalWriter; 239 friend class NPT_XmlParser; 240 friend class NPT_XmlProcessor; 241 friend class NPT_XmlNamespaceCollapser; 242 }; 243 244 /*---------------------------------------------------------------------- 245 | NPT_XmlTextNode 246 +---------------------------------------------------------------------*/ 247 class NPT_XmlTextNode : public NPT_XmlNode 248 { 249 public: 250 // types 251 typedef enum { 252 CHARACTER_DATA, 253 IGNORABLE_WHITESPACE, 254 CDATA_SECTION, 255 ENTITY_REFERENCE, 256 COMMENT 257 } TokenType; 258 259 // constructor 260 NPT_XmlTextNode(TokenType token_type, const char* text); 261 262 // methods GetString()263 const NPT_String& GetString() const { return m_Text; } 264 265 // type casting AsTextNode()266 NPT_XmlTextNode* AsTextNode() { return this; } AsTextNode()267 const NPT_XmlTextNode* AsTextNode() const { return this; } 268 269 private: 270 // members 271 // TokenType m_TokenType; 272 NPT_String m_Text; 273 }; 274 275 /*---------------------------------------------------------------------- 276 | NPT_XmlParser 277 +---------------------------------------------------------------------*/ 278 class NPT_XmlParser 279 { 280 public: 281 // methods 282 NPT_XmlParser(bool keep_whitespace = true); 283 virtual ~NPT_XmlParser(); 284 virtual NPT_Result Parse(const char* xml, 285 NPT_XmlNode*& tree, 286 bool incremental=false); 287 virtual NPT_Result Parse(const char* xml, 288 NPT_Size size, 289 NPT_XmlNode*& tree, 290 bool incremental=false); 291 virtual NPT_Result Parse(NPT_InputStream& stream, 292 NPT_XmlNode*& tree, 293 bool incremental=false); 294 virtual NPT_Result Parse(NPT_InputStream& stream, 295 NPT_Size& size, 296 NPT_XmlNode*& tree, 297 bool incremental=false); 298 299 protected: 300 // NPT_XmlHandler methods 301 NPT_Result OnStartElement(const char* name); 302 NPT_Result OnElementAttribute(const char* name, const char* value); 303 NPT_Result OnEndElement(const char* name); 304 NPT_Result OnCharacterData(const char* data, unsigned long size); 305 void RemoveIgnorableWhitespace(); 306 307 // members 308 NPT_XmlProcessor* m_Processor; 309 NPT_XmlElementNode* m_Root; 310 NPT_XmlElementNode* m_CurrentElement; 311 bool m_KeepWhitespace; 312 313 private: 314 void Reset(); 315 316 // friends 317 friend class NPT_XmlProcessor; 318 }; 319 320 /*---------------------------------------------------------------------- 321 | NPT_XmlSerializer 322 +---------------------------------------------------------------------*/ 323 class NPT_XmlSerializer 324 { 325 public: 326 // methods 327 NPT_XmlSerializer(NPT_OutputStream* output, 328 NPT_Cardinal indentation = 0, 329 bool shrink_empty_elements = true, 330 bool add_xml_decl = false); 331 virtual ~NPT_XmlSerializer(); 332 virtual NPT_Result StartDocument(); 333 virtual NPT_Result EndDocument(); 334 virtual NPT_Result StartElement(const char* prefix, const char* name); 335 virtual NPT_Result EndElement(const char* prefix, const char* name); 336 virtual NPT_Result Attribute(const char* prefix, const char* name, const char* value); 337 virtual NPT_Result Text(const char* text); 338 virtual NPT_Result CdataSection(const char* data); 339 virtual NPT_Result Comment(const char* comment); 340 341 protected: 342 // methods 343 void EscapeChar(unsigned char c, char* text); 344 NPT_Result ProcessPending(); 345 NPT_Result OutputEscapedString(const char* text, bool attribute); 346 void OutputIndentation(bool start); 347 348 // members 349 NPT_OutputStream* m_Output; 350 bool m_ElementPending; 351 NPT_Cardinal m_Depth; 352 NPT_Cardinal m_Indentation; 353 NPT_String m_IndentationPrefix; 354 bool m_ElementHasText; 355 bool m_ShrinkEmptyElements; 356 bool m_AddXmlDecl; 357 }; 358 359 /*---------------------------------------------------------------------- 360 | NPT_XmlWriter 361 +---------------------------------------------------------------------*/ 362 class NPT_XmlWriter 363 { 364 public: 365 // constructor m_Indentation(indentation)366 explicit NPT_XmlWriter(NPT_Cardinal indentation = 0) : m_Indentation(indentation) {} 367 368 // methods 369 NPT_Result Serialize(NPT_XmlNode& node, 370 NPT_OutputStream& stream, 371 bool add_xml_decl = false); 372 373 private: 374 // members 375 NPT_Cardinal m_Indentation; 376 }; 377 378 /*---------------------------------------------------------------------- 379 | NPT_XmlCanonicalizer 380 +---------------------------------------------------------------------*/ 381 class NPT_XmlCanonicalizer 382 { 383 public: 384 // methods 385 NPT_Result Serialize(NPT_XmlNode& node, 386 NPT_OutputStream& stream, 387 bool add_xml_decl = false); 388 }; 389 390 #endif // _NPT_XML_H_ 391