1 /*****************************************************************
3 | Neptune - Xml Support
5 | Copyright (c) 2002-2008, Axiomatic Systems, LLC.
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.
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.
30 ****************************************************************/
35 /*----------------------------------------------------------------------
37 +---------------------------------------------------------------------*/
40 #include "NptStrings.h"
41 #include "NptStreams.h"
43 /*----------------------------------------------------------------------
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;
51 #define NPT_XML_ANY_NAMESPACE "*"
52 #define NPT_XML_NO_NAMESPACE NULL
54 /*----------------------------------------------------------------------
55 | forward declarations
56 +---------------------------------------------------------------------*/
57 class NPT_XmlProcessor
;
59 /*----------------------------------------------------------------------
61 +---------------------------------------------------------------------*/
62 class NPT_XmlAttribute
66 NPT_XmlAttribute(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
) {}
69 const NPT_String
& GetPrefix() const { return m_Prefix
; }
70 const NPT_String
& GetName() const { return m_Name
; }
71 const NPT_String
& GetValue() const { return m_Value
; }
72 void SetValue(const char* value
) { m_Value
= value
; }
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
);
87 friend class NPT_XmlAttributeFinder
;
88 friend class NPT_XmlAttributeFinderWithPrefix
;
91 /*----------------------------------------------------------------------
93 +---------------------------------------------------------------------*/
94 class NPT_XmlNamespaceMap
98 ~NPT_XmlNamespaceMap();
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
);
110 Entry(const char* prefix
, const char* uri
) :
111 m_Prefix(prefix
), m_Uri(uri
) {}
119 NPT_List
<Entry
*> m_Entries
;
122 friend class NPT_XmlWriter
;
123 friend class NPT_XmlNodeWriter
;
124 friend class NPT_XmlNodeCanonicalWriter
;
127 /*----------------------------------------------------------------------
129 +---------------------------------------------------------------------*/
130 class NPT_XmlElementNode
;
131 class NPT_XmlTextNode
;
143 NPT_XmlNode(Type type
) : m_Type(type
), m_Parent(NULL
) {}
144 virtual ~NPT_XmlNode() {}
145 Type
GetType() const { return m_Type
; }
146 NPT_XmlNode
* GetParent() const { return m_Parent
; }
149 virtual NPT_XmlElementNode
* AsElementNode() { return NULL
; }
150 virtual const NPT_XmlElementNode
* AsElementNode() const { return NULL
; }
151 virtual NPT_XmlTextNode
* AsTextNode() { return NULL
; }
152 virtual const NPT_XmlTextNode
* AsTextNode() const { return NULL
; }
156 virtual void SetParent(NPT_XmlNode
* parent
) { m_Parent
= parent
; }
160 NPT_XmlNode
* m_Parent
;
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()
169 /*----------------------------------------------------------------------
171 +---------------------------------------------------------------------*/
172 class NPT_XmlElementNode
: public NPT_XmlNode
176 NPT_XmlElementNode(const char* tag
);
177 NPT_XmlElementNode(const char* prefix
, const char* tag
);
178 ~NPT_XmlElementNode() override
;
179 NPT_List
<NPT_XmlNode
*>& GetChildren() { return m_Children
; }
180 const NPT_List
<NPT_XmlNode
*>&
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
,
189 NPT_Result
SetAttribute(const char* name
,
191 NPT_Result
AddText(const char* text
);
192 NPT_List
<NPT_XmlAttribute
*>&
193 GetAttributes() { return m_Attributes
; }
194 const NPT_List
<NPT_XmlAttribute
*>&
195 GetAttributes() const { return m_Attributes
; }
196 const NPT_String
* GetAttribute(const char* name
,
197 const char* namespc
= NPT_XML_NO_NAMESPACE
) const;
198 const NPT_String
& GetPrefix() const { return m_Prefix
; }
199 const NPT_String
& GetTag() const { return m_Tag
; }
200 const NPT_String
* GetText(NPT_Ordinal n
=0) const;
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();
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;
214 NPT_XmlElementNode
* AsElementNode() override
{ return this; }
215 const NPT_XmlElementNode
* AsElementNode() const override
{ return this; }
219 void SetParent(NPT_XmlNode
* parent
) override
;
220 void SetNamespaceParent(NPT_XmlElementNode
* parent
);
221 void RelinkNamespaceMaps();
223 NPT_Result
AddAttribute(const char* name
, const char* value
);
228 NPT_List
<NPT_XmlNode
*> m_Children
;
229 NPT_List
<NPT_XmlAttribute
*> m_Attributes
;
230 NPT_XmlNamespaceMap
* m_NamespaceMap
;
231 NPT_XmlElementNode
* m_NamespaceParent
;
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
;
244 /*----------------------------------------------------------------------
246 +---------------------------------------------------------------------*/
247 class NPT_XmlTextNode
: public NPT_XmlNode
253 IGNORABLE_WHITESPACE
,
260 NPT_XmlTextNode(TokenType token_type
, const char* text
);
263 const NPT_String
& GetString() const { return m_Text
; }
264 TokenType
GetTokenType() const { return m_TokenType
; }
267 NPT_XmlTextNode
* AsTextNode() override
{ return this; }
268 const NPT_XmlTextNode
* AsTextNode() const override
{ return this; }
272 TokenType m_TokenType
;
276 /*----------------------------------------------------------------------
278 +---------------------------------------------------------------------*/
283 NPT_XmlParser(bool keep_whitespace
= true);
284 virtual ~NPT_XmlParser();
285 virtual NPT_Result
Parse(const char* xml
,
287 bool incremental
=false);
288 virtual NPT_Result
Parse(const char* xml
,
291 bool incremental
=false);
292 virtual NPT_Result
Parse(NPT_InputStream
& stream
,
294 bool incremental
=false);
295 virtual NPT_Result
Parse(NPT_InputStream
& stream
,
298 bool incremental
=false);
301 // NPT_XmlHandler methods
302 NPT_Result
OnStartElement(const char* name
);
303 NPT_Result
OnElementAttribute(const char* name
, const char* value
);
304 NPT_Result
OnEndElement(const char* name
);
305 NPT_Result
OnCharacterData(const char* data
, NPT_Size size
);
306 void RemoveIgnorableWhitespace();
309 NPT_XmlProcessor
* m_Processor
;
310 NPT_XmlElementNode
* m_Root
;
311 NPT_XmlElementNode
* m_CurrentElement
;
312 bool m_KeepWhitespace
;
318 friend class NPT_XmlProcessor
;
321 /*----------------------------------------------------------------------
323 +---------------------------------------------------------------------*/
324 class NPT_XmlSerializer
328 NPT_XmlSerializer(NPT_OutputStream
* output
,
329 NPT_Cardinal indentation
= 0,
330 bool shrink_empty_elements
= true,
331 bool add_xml_decl
= false);
332 virtual ~NPT_XmlSerializer();
333 virtual NPT_Result
StartDocument();
334 virtual NPT_Result
EndDocument();
335 virtual NPT_Result
StartElement(const char* prefix
, const char* name
);
336 virtual NPT_Result
EndElement(const char* prefix
, const char* name
);
337 virtual NPT_Result
Attribute(const char* prefix
, const char* name
, const char* value
);
338 virtual NPT_Result
Text(const char* text
);
339 virtual NPT_Result
CdataSection(const char* data
);
340 virtual NPT_Result
Comment(const char* comment
);
344 void EscapeChar(unsigned char c
, char* text
);
345 NPT_Result
ProcessPending();
346 NPT_Result
OutputEscapedString(const char* text
, bool attribute
);
347 void OutputIndentation(bool start
);
350 NPT_OutputStream
* m_Output
;
351 bool m_ElementPending
;
352 NPT_Cardinal m_Depth
;
353 NPT_Cardinal m_Indentation
;
354 NPT_String m_IndentationPrefix
;
355 bool m_ElementHasText
;
356 bool m_ShrinkEmptyElements
;
360 /*----------------------------------------------------------------------
362 +---------------------------------------------------------------------*/
367 explicit NPT_XmlWriter(NPT_Cardinal indentation
= 0) : m_Indentation(indentation
) {}
370 NPT_Result
Serialize(NPT_XmlNode
& node
,
371 NPT_OutputStream
& stream
,
372 bool add_xml_decl
= false);
376 NPT_Cardinal m_Indentation
;
379 /*----------------------------------------------------------------------
380 | NPT_XmlCanonicalizer
381 +---------------------------------------------------------------------*/
382 class NPT_XmlCanonicalizer
386 NPT_Result
Serialize(NPT_XmlNode
& node
,
387 NPT_OutputStream
& stream
,
388 bool add_xml_decl
= false);
391 #endif // _NPT_XML_H_