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