comparison deps/Platinum/Source/Core/PltXmlHelper.h @ 0:3425707ddbf6

Initial import (hopefully this mercurial stuff works...)
author fraserofthenight
date Mon, 06 Jul 2009 08:06:28 -0700
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:3425707ddbf6
1 /*****************************************************************
2 |
3 | Platinum - Xml Helper
4 |
5 | Copyright (c) 2004-2008, Plutinosoft, LLC.
6 | All rights reserved.
7 | http://www.plutinosoft.com
8 |
9 | This program is free software; you can redistribute it and/or
10 | modify it under the terms of the GNU General Public License
11 | as published by the Free Software Foundation; either version 2
12 | of the License, or (at your option) any later version.
13 |
14 | OEMs, ISVs, VARs and other distributors that combine and
15 | distribute commercially licensed software with Platinum software
16 | and do not wish to distribute the source code for the commercially
17 | licensed software under version 2, or (at your option) any later
18 | version, of the GNU General Public License (the "GPL") must enter
19 | into a commercial license agreement with Plutinosoft, LLC.
20 |
21 | This program is distributed in the hope that it will be useful,
22 | but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | GNU General Public License for more details.
25 |
26 | You should have received a copy of the GNU General Public License
27 | along with this program; see the file LICENSE.txt. If not, write to
28 | the Free Software Foundation, Inc.,
29 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
30 | http://www.gnu.org/licenses/gpl-2.0.html
31 |
32 ****************************************************************/
33
34 #ifndef _PLT_XML_HELPER_H_
35 #define _PLT_XML_HELPER_H_
36
37 /*----------------------------------------------------------------------
38 | includes
39 +---------------------------------------------------------------------*/
40 #include "Neptune.h"
41 /*----------------------------------------------------------------------
42 | PLT_XmlAttributeFinder
43 +---------------------------------------------------------------------*/
44 class PLT_XmlAttributeFinder
45 {
46 public:
47 // if 'namespc' is NULL, we're looking for ANY namespace
48 // if 'namespc' is '\0', we're looking for NO namespace
49 // if 'namespc' is non-empty, look for that SPECIFIC namespace
50 PLT_XmlAttributeFinder(const NPT_XmlElementNode& element,
51 const char* name,
52 const char* namespc) :
53 m_Element(element), m_Name(name), m_Namespace(namespc) {}
54
55 bool operator()(const NPT_XmlAttribute* const & attribute) const {
56 if (attribute->GetName() == m_Name) {
57 if (m_Namespace) {
58 const NPT_String& prefix = attribute->GetPrefix();
59 if (m_Namespace[0] == '\0') {
60 // match if the attribute has NO namespace
61 return prefix.IsEmpty();
62 } else {
63 // match if the attribute has the SPECIFIC namespace
64 // we're looking for
65 const NPT_String* namespc = m_Element.GetNamespaceUri(prefix);
66 return namespc && *namespc == m_Namespace;
67 }
68 } else {
69 // ANY namespace will match
70 return true;
71 }
72 } else {
73 return false;
74 }
75 }
76
77 private:
78 const NPT_XmlElementNode& m_Element;
79 const char* m_Name;
80 const char* m_Namespace;
81 };
82
83 /*----------------------------------------------------------------------
84 | PLT_XmlHelper
85 +---------------------------------------------------------------------*/
86 class PLT_XmlHelper
87 {
88 public:
89
90 // static methods
91 static NPT_Result GetChildText(NPT_XmlElementNode* node,
92 const char* tag,
93 NPT_String& value,
94 const char* namespc = "") {
95 value = "";
96
97 if (!node) return NPT_FAILURE;
98
99 // special case "" means we look for the same namespace as the parent
100 if (namespc && namespc[0] == '\0') namespc = node->GetNamespace()?node->GetNamespace()->GetChars():NPT_XML_NO_NAMESPACE;
101
102 NPT_XmlElementNode* child = node->GetChild(tag, namespc);
103 if (!child) return NPT_FAILURE;
104
105 const NPT_String* text = child->GetText();
106 value = text?*text:"";
107 return NPT_SUCCESS;
108 }
109
110
111 static NPT_Result GetAttribute(NPT_XmlElementNode* node,
112 const char* name,
113 NPT_XmlAttribute*& attr,
114 const char* namespc = "") {
115 attr = NULL;
116
117 if (!node) return NPT_FAILURE;
118
119 // special case "" means we look for the same namespace as the parent
120 if (namespc && namespc[0] == '\0') namespc = node->GetNamespace()?node->GetNamespace()->GetChars():NPT_XML_NO_NAMESPACE;
121
122 NPT_List<NPT_XmlAttribute*>::Iterator attribute;
123 attribute = node->GetAttributes().Find(PLT_XmlAttributeFinder(*node, name, namespc));
124 if (!attribute) return NPT_FAILURE;
125
126 attr = (*attribute);
127 return NPT_SUCCESS;
128 }
129
130
131 static NPT_Result GetAttribute(NPT_XmlElementNode* node,
132 const char* name,
133 NPT_String& value,
134 const char* namespc = "") {
135 value = "";
136
137 NPT_XmlAttribute* attribute = NULL;
138 NPT_CHECK(GetAttribute(node, name, attribute, namespc));
139 if (!attribute) return NPT_FAILURE;
140
141 value = attribute->GetValue();
142 return NPT_SUCCESS;
143 }
144
145 static NPT_Result AddChildText(NPT_XmlElementNode* node,
146 const char* tag,
147 const char* text,
148 const char* prefix = NULL) {
149 if (!node) return NPT_FAILURE;
150 NPT_XmlElementNode* child = new NPT_XmlElementNode(prefix, tag);
151 child->AddText(text);
152 return node->AddChild(child);
153 }
154
155 static bool IsMatch(const NPT_XmlNode* const & node, const char* tag, const char* namespc_mapped) {
156 // if m_Namespace is NULL, we're looking for ANY namespace
157 // if m_Namespace is '\0', we're looking for NO namespace
158 // if m_Namespace is non-empty, look for that SPECIFIC namespace
159
160 const NPT_XmlElementNode* element = node->AsElementNode();
161 // is tag the same (case sensitive)?
162 if (element && element->GetTag() == tag) {
163 if (namespc_mapped) {
164 // look for a SPECIFIC namespace or NO namespace
165 const NPT_String* namespc = element->GetNamespace();
166 if (namespc) {
167 // the element has a namespace, match if it is equal to
168 // what we're looking for
169 return *namespc == namespc_mapped;
170 } else {
171 // the element does not have a namespace, match if we're
172 // looking for NO namespace
173 return namespc_mapped[0] == '\0';
174 }
175 } else {
176 // ANY namespace will match
177 return true;
178 }
179 }
180 return false;
181 }
182
183 static NPT_Result GetChildren(NPT_XmlElementNode* node,
184 NPT_Array<NPT_XmlElementNode*>& children,
185 const char* tag,
186 const char* namespc = "") {
187 if (!node) return NPT_FAILURE;
188
189 // special case "" means we look for the same namespace as the parent
190 if (namespc && namespc[0] == '\0') namespc = node->GetNamespace()?node->GetNamespace()->GetChars():NPT_XML_NO_NAMESPACE;
191
192 const char* namespc_mapped = (namespc==NULL)?"":(namespc[0]=='*' && namespc[1]=='\0')?NULL:namespc;
193
194 // get all children first
195 NPT_List<NPT_XmlNode*>& allchildren = node->GetChildren();
196
197 // iterate through children and add only elements with matching tag
198 NPT_List<NPT_XmlNode*>::Iterator child = allchildren.GetFirstItem();
199 while (child) {
200 if (IsMatch(*child, tag, namespc_mapped)) {
201 children.Add((*child)->AsElementNode());
202 }
203 ++child;
204 }
205 return NPT_SUCCESS;
206 }
207
208 static NPT_XmlElementNode* GetChild(NPT_XmlElementNode* node,
209 const char* tag,
210 const char* namespc = "") {
211 if (!node) return NULL;
212
213 // special case "" means we look for the same namespace as the parent
214 if (namespc && namespc[0] == '\0') namespc = node->GetNamespace()?node->GetNamespace()->GetChars():NPT_XML_NO_NAMESPACE;
215
216 return node->GetChild(tag, namespc);
217 }
218
219 static NPT_Result GetChild(NPT_XmlElementNode* parent,
220 NPT_XmlElementNode*& child,
221 NPT_Ordinal n = 0) {
222 if (!parent) return NPT_FAILURE;
223
224 // reset child
225 child = NULL;
226
227 // get all children first
228 NPT_List<NPT_XmlNode*>::Iterator children = parent->GetChildren().GetFirstItem();
229 while (children) {
230 if ((*children)->AsElementNode() && n-- == 0) {
231 child = (*children)->AsElementNode();
232 return NPT_SUCCESS;
233 }
234 children++;
235 }
236
237 return NPT_FAILURE;
238 }
239
240 static NPT_Result Serialize(NPT_XmlNode& node, NPT_String& xml) {
241 NPT_XmlWriter writer(2);
242 NPT_MemoryStreamReference stream(new NPT_MemoryStream());
243 NPT_CHECK(writer.Serialize(node, *stream));
244
245 NPT_LargeSize size;
246 stream->GetAvailable(size);
247 if (size != (NPT_Size)size) return NPT_ERROR_OUT_OF_RANGE;
248
249 xml.Reserve((NPT_Size)size);
250 stream->Read(xml.UseChars(), (NPT_Size)size);
251 xml.SetLength((NPT_Size)size);
252 return NPT_SUCCESS;
253 }
254 private:
255 // members
256 };
257
258 #endif // _PLT_XML_HELPER_H_
259
260
261
262
263
264
265
266
267