DCL 3.7.4
Loading...
Searching...
No Matches
XMLParser.cpp
Go to the documentation of this file.
1#include <dcl/XMLParser.h>
2#include <dcl/Charset.h>
3
29
30#if !defined(__WINNT__) && defined(XML_UNICODE_WCHAR_T)
31 #error "You must not define XML_UNICODE_WCHAR_T for UNIX Operating System"
32#endif
33
34#if __DCL_HAVE_THIS_FILE__
35#undef __THIS_FILE__
36static const char_t __THIS_FILE__[] = __T("dcl/XmlParser.cpp");
37#endif
38
39__DCL_BEGIN_NAMESPACE
40
42
43XmlException::XmlException(XML_Parser _parser)
44{
45 const XML_LChar* psz = XML_ErrorString(XML_GetErrorCode(_parser));
46 const wchar_t* wpsz = NULL;
47#ifdef XML_UNICODE_WCHAR_T
48 wpsz = psz;
49#else
50 UTF8Decoder decoder;
51 String str = decoder.decode(psz);
52 wpsz = str.data();
53#endif
54 __message = String::format(
55 __T("%ls at line %d"),
56 wpsz,
57 XML_GetCurrentLineNumber(_parser)
58 );
59}
60
62{
63 return __message;
64}
65
67
68void XmlDefaultHandler::startElement(
69 void* _userData, const XML_Char* _name, const XML_Char** _attrs
70)
71{
72#ifdef XML_UNICODE_WCHAR_T
73 String name = _name;
74 StringStringArray attrs;
75 while (*_attrs) {
76 String key = *_attrs++;
77 String value = *_attrs++;
78 attrs.add(StringString(key, value));
79 }
80#else
81 UTF8Decoder decoder;
82 String name = decoder.decode(_name);
83 StringStringArray attrs;
84 while (*_attrs) {
85 String key = decoder.decode(*_attrs++);
86 String value = decoder.decode(*_attrs++);
87 attrs.add(StringString(key, value));
88 }
89#endif
90 XmlDefaultHandler* pHandler = (XmlDefaultHandler*) _userData;
91 pHandler->startElement(name, attrs);
92}
93
94void XmlDefaultHandler::endElement(
95 void* _userData, const XML_Char* _name
96)
97{
98#ifdef XML_UNICODE_WCHAR_T
99 String name = _name;
100#else
101 UTF8Decoder decoder;
102 String name = decoder.decode(_name);
103#endif
104 XmlDefaultHandler* pHandler = (XmlDefaultHandler*) _userData;
105 pHandler->endElement(name);
106}
107
108void XmlDefaultHandler::characters(
109 void* _userData, const XML_Char* _chars, int _len)
110{
111#ifdef XML_UNICODE_WCHAR_T
112 String chars(_chars, _len);
113#else
114 UTF8Decoder decoder;
115 String chars = decoder.decode(_chars, _len);
116#endif
117 // startElement, endElement 사이에서 LF를 구별하여
118 XmlDefaultHandler* pHandler = (XmlDefaultHandler*) _userData;
119 pHandler->characters(chars);
120}
121
122void XmlDefaultHandler::startElement(
123 const String& _name, const StringStringArray& _attrs
124)
125{
126 __DCL_TRACE2(__T("startElement[%ls], attrs[%ls]\n"), _name.data(), _attrs.toString().data());
127}
128
129void XmlDefaultHandler::endElement(
130 const String& _name)
131{
132 __DCL_TRACE1(__T("endElement[%ls]\n"), _name.data());
133}
134
135void XmlDefaultHandler::characters(
136 const String& _chars
137)
138{
139 __DCL_TRACE1(__T("characters[%ls]\n"), _chars.data());
140}
141
143
145{
146 __parser = XML_ParserCreate(NULL);
147}
148
150{
151 XML_ParserFree(__parser);
152}
153
155 const ByteString& _data, XmlDefaultHandler& _handler
157{
158 XML_SetElementHandler(
159 __parser,
160 XmlDefaultHandler::startElement,
161 XmlDefaultHandler::endElement
162 );
163
164 XML_SetCharacterDataHandler(
165 __parser,
166 XmlDefaultHandler::characters
167 );
168
169 XML_SetUserData(__parser, &_handler);
170
171 XML_Status status = XML_Parse(
172 __parser,
173 _data,
174 (int)_data.length(),
175 1 // done
176 );
177
178 if (status == XML_STATUS_ERROR) {
179 throw new XmlException(__parser);
180 }
181
182}
183
184/*
185 References
186 http://www.w3.org/DOM/DOMTR#dom2
187*/
188
190
192
193String XmlCharsNode::toString() const
194{
195 return __chars;
196}
197
198XmlCharsNode::XmlCharsNode(XmlNode* _parentNode, const String& _chars)
199 : XmlNode(_parentNode)
200{
201 __chars = _chars;
202}
203
205
206String XmlElement::toString() const
207{
208 StringBuilder r;
209
210 r.append(__T("<")).append(__name);
211 for (StringStringArray::ConstIterator it = __attrs.begin();
212 it != __attrs.end(); it++) {
213 r.append(__T(" ")).append((*it).key).append(__T("=\""))
214 .append(String::escape((*it).value, (*it).value.length(), String::ESCAPE_XML))
215 .append(__T("\""));
216 }
217
218 if (__children.isEmpty()) {
219 r.append(__T(" >"));
220 }
221 else {
222 r.append(__T(">"))
223 .append(innerXml())
224 .append(__T("</")).append(__name).append(__T(">"));
225 }
226
227 return r;
228}
229
231const String& _name, const StringStringArray& _attrs
232) : XmlNode(_parentNode)
233{
234 __name = _name;
235 __attrs = _attrs;
236}
237
239{
240 for (PointerArray::Iterator it = __children.begin();
241 it != __children.end(); it++) {
242 delete ((XmlNode*)(*it));
243 }
244}
245
247{
248 __children.add(_node);
249}
250
251const String XmlElement::innerText() const
252{
253 StringBuilder r;
254
255 for (PointerArray::ConstIterator it = __children.begin();
256 it != __children.end(); it++
257 ) {
258 XmlNode* p = (XmlNode*)(*it);
260 r.append(((XmlElement*) p)->innerText());
261 }
262 else {
263 r.append(p->toString());
264 }
265 }
266
267 return r;
268}
269
270const String XmlElement::innerXml() const
271{
272 StringBuilder r;
273
274 for (PointerArray::ConstIterator it = __children.begin();
275 it != __children.end(); it++
276 ) {
277 XmlNode* p = (XmlNode*)(*it);
279 String s = p->toString();
280 r.append(String::escape(s, s.length(), String::ESCAPE_XML));
281 }
282 else {
283 r.append(((XmlNode*)(*it))->toString());
284 }
285 }
286 return r;
287}
288
290
291String XmlDocument::toString() const
292{
293 String s;
294 if (__topElement)
295 s = __topElement->toString();
296 return s;
297}
298
300{
301 __currentElement = NULL;
302 __topElement = NULL;
303}
304
306{
307 if (__topElement) {
308 delete __topElement;
309#ifdef __DCL_DEBUG
310 __topElement = NULL;
311#endif
312 }
313}
314
315void XmlDocument::startElement(const String& _name, const StringStringArray& _attrs)
316{
317 XmlElement* pElement = new XmlElement(__currentElement, _name, _attrs);
318 if (!__topElement)
319 __topElement = pElement;
320 else
321 __currentElement->addChildNode(pElement);
322
323 __currentElement = pElement;
324}
325
326void XmlDocument::endElement(const String& _name)
327{
328 __DCL_ASSERT(__currentElement != NULL && __currentElement->name() == _name);
329
330 XmlNode* pParentNode = __currentElement->parentNode();
331#ifdef __DCL_DEBUG
332 if (__currentElement != __topElement) {
333 __DCL_ASSERT(pParentNode != NULL
334 && pParentNode->isInstanceOf(CLASSINFO(XmlElement)));
335 }
336#endif
337 __currentElement = (XmlElement*) pParentNode;
338}
339
340void XmlDocument::characters(const String& _chars)
341{
342 XmlCharsNode* charsNode = new XmlCharsNode(__currentElement, _chars);
343 __currentElement->addChildNode(charsNode);
344}
345
346__DCL_END_NAMESPACE
#define __THIS_FILE__
Definition _trace.h:14
#define NULL
Definition Config.h:312
wchar_t char_t
Definition Config.h:247
#define __DCL_THROWS1(e)
Definition Config.h:152
IOException *size_t r
Definition MediaInfo.cpp:82
#define __DCL_TRACE1(fmt, arg1)
Definition Object.h:399
#define CLASSINFO(class_name)
Definition Object.h:226
#define __DCL_ASSERT(expr)
Definition Object.h:394
#define IMPLEMENT_CLASSINFO(class_name, base_class_name)
Definition Object.h:245
#define __T(str)
Definition Object.h:60
#define __DCL_TRACE2(fmt, arg1, arg2)
Definition Object.h:400
virtual String toString() const
Definition Object.cpp:187
bool isInstanceOf(const std::type_info &typeinfo) const
Definition Object.cpp:168
virtual String toString() const
XmlCharsNode(XmlNode *_parentNode, const String &_chars)
virtual String toString() const
virtual ~XmlDocument()
virtual ~XmlElement()
void addChildNode(XmlNode *_node)
const String innerText() const
virtual String toString() const
const String innerXml() const
XmlElement(XmlNode *_parentNode, const String &_name, const StringStringArray &_attrs)
virtual String toString() const
Definition XMLParser.cpp:61
XmlException(XML_Parser _parser)
XmlNode(XmlNode *_parentNode)
Definition XMLParser.h:114
void parse(const ByteString &_data, XmlDefaultHandler &_handler) __DCL_THROWS1(XmlException *)
virtual ~XmlParser()