1//
2// XMLStreamParserTest.cpp
3//
4// Copyright (c) 2015, Applied Informatics Software Engineering GmbH.
5// and Contributors.
6//
7// SPDX-License-Identifier: BSL-1.0
8//
9
10#include "XMLStreamParserTest.h"
11#include "Poco/CppUnit/TestCaller.h"
12#include "Poco/CppUnit/TestSuite.h"
13#include "Poco/XML/XMLStreamParser.h"
14#include "Poco/Exception.h"
15#include <sstream>
16#include <string>
17#include <vector>
18#include <iostream>
19
20
21using namespace Poco::XML;
22
23
24XMLStreamParserTest::XMLStreamParserTest(const std::string& name):
25 CppUnit::TestCase(name)
26{
27}
28
29
30XMLStreamParserTest::~XMLStreamParserTest()
31{
32}
33
34
35void XMLStreamParserTest::testParser()
36{
37 // Test error handling.
38 //
39 try
40 {
41 std::istringstream is("<root><nested>X</nasted></root>");
42 XMLStreamParser p(is, "test");
43
44 assertTrue (p.next() == XMLStreamParser::EV_START_ELEMENT);
45 assertTrue (p.next() == XMLStreamParser::EV_START_ELEMENT);
46 assertTrue (p.next() == XMLStreamParser::EV_CHARACTERS && p.value() == "X");
47 p.next();
48 assertTrue (false);
49 }
50 catch (const Poco::Exception&)
51 {
52 // cerr << e.what () << endl;
53 }
54
55 try
56 {
57 std::istringstream is("<root/>");
58 is.exceptions(std::ios_base::badbit | std::ios_base::failbit);
59 XMLStreamParser p(is, "test");
60
61 is.setstate(std::ios_base::badbit);
62 p.next();
63 assertTrue (false);
64 }
65 catch (const std::ios_base::failure&)
66 {
67 }
68
69 // Test the nextExpect() functionality.
70 //
71 {
72 std::istringstream is("<root/>");
73 XMLStreamParser p(is, "test");
74 p.nextExpect(XMLStreamParser::EV_START_ELEMENT, "root");
75 p.nextExpect(XMLStreamParser::EV_END_ELEMENT);
76 }
77
78 try
79 {
80 std::istringstream is("<root/>");
81 XMLStreamParser p(is, "test");
82 p.nextExpect(XMLStreamParser::EV_END_ELEMENT);
83 assertTrue (false);
84 }
85 catch (const Poco::Exception&)
86 {
87 // cerr << e.what () << endl;
88 }
89
90 try
91 {
92 std::istringstream is("<root/>");
93 XMLStreamParser p(is, "test");
94 p.nextExpect(XMLStreamParser::EV_START_ELEMENT, "root1");
95 assertTrue (false);
96 }
97 catch (const Poco::Exception&)
98 {
99 // cerr << e.what () << endl;
100 }
101
102 // Test nextExpect() with content setting.
103 //
104 {
105 std::istringstream is("<root> </root>");
106 XMLStreamParser p(is, "empty");
107
108 p.nextExpect(XMLStreamParser::EV_START_ELEMENT, "root", Content::Empty);
109 p.nextExpect(XMLStreamParser::EV_END_ELEMENT);
110 p.nextExpect(XMLStreamParser::EV_EOF);
111 }
112
113 // Test namespace declarations.
114 //
115 {
116 // Followup end element event that should be precedeeded by end
117 // namespace declaration.
118 //
119 std::istringstream is("<root xmlns:a='a'/>");
120 XMLStreamParser p(is, "test", XMLStreamParser::RECEIVE_DEFAULT | XMLStreamParser::RECEIVE_NAMESPACE_DECLS);
121
122 p.nextExpect(XMLStreamParser::EV_START_ELEMENT, "root");
123 p.nextExpect(XMLStreamParser::EV_START_NAMESPACE_DECL);
124 p.nextExpect(XMLStreamParser::EV_END_NAMESPACE_DECL);
125 p.nextExpect(XMLStreamParser::EV_END_ELEMENT);
126 }
127
128 // Test value extraction.
129 //
130 {
131 std::istringstream is("<root>123</root>");
132 XMLStreamParser p(is, "test");
133 p.nextExpect(XMLStreamParser::EV_START_ELEMENT, "root");
134 p.nextExpect(XMLStreamParser::EV_CHARACTERS);
135 assertTrue (p.value<int>() == 123);
136 p.nextExpect(XMLStreamParser::EV_END_ELEMENT);
137 }
138
139 // Test attribute maps.
140 //
141 {
142 std::istringstream is("<root a='a' b='b' d='123' t='true'/>");
143 XMLStreamParser p(is, "test");
144 p.nextExpect(XMLStreamParser::EV_START_ELEMENT, "root");
145
146 assertTrue (p.attribute("a") == "a");
147 assertTrue (p.attribute("b", "B") == "b");
148 assertTrue (p.attribute("c", "C") == "C");
149 assertTrue (p.attribute<int>("d") == 123);
150 assertTrue (p.attribute<bool>("t") == true);
151 assertTrue (p.attribute("f", false) == false);
152
153 p.nextExpect(XMLStreamParser::EV_END_ELEMENT);
154 }
155
156 {
157 std::istringstream is("<root a='a'><nested a='A'><inner/></nested></root>");
158 XMLStreamParser p(is, "test");
159 p.nextExpect(XMLStreamParser::EV_START_ELEMENT, "root");
160 assertTrue (p.attribute("a") == "a");
161 assertTrue (p.peek() == XMLStreamParser::EV_START_ELEMENT && p.localName() == "nested");
162 assertTrue (p.attribute("a") == "a");
163 p.nextExpect(XMLStreamParser::EV_START_ELEMENT, "nested");
164 assertTrue (p.attribute("a") == "A");
165 p.nextExpect(XMLStreamParser::EV_START_ELEMENT, "inner");
166 assertTrue (p.attribute("a", "") == "");
167 p.nextExpect(XMLStreamParser::EV_END_ELEMENT);
168 assertTrue (p.attribute("a") == "A");
169 assertTrue (p.peek() == XMLStreamParser::EV_END_ELEMENT);
170 assertTrue (p.attribute("a") == "A"); // Still valid.
171 p.nextExpect(XMLStreamParser::EV_END_ELEMENT);
172 assertTrue (p.attribute("a") == "a");
173 p.nextExpect(XMLStreamParser::EV_END_ELEMENT);
174 assertTrue (p.attribute("a", "") == "");
175 }
176
177 try
178 {
179 std::istringstream is("<root a='a' b='b'/>");
180 XMLStreamParser p(is, "test");
181 p.nextExpect(XMLStreamParser::EV_START_ELEMENT, "root");
182 assertTrue (p.attribute("a") == "a");
183 p.nextExpect(XMLStreamParser::EV_END_ELEMENT);
184 assertTrue (false);
185 }
186 catch (const Poco::Exception&)
187 {
188 // cerr << e.what () << endl;
189 }
190
191 try
192 {
193 std::istringstream is("<root a='abc'/>");
194 XMLStreamParser p(is, "test");
195 p.nextExpect(XMLStreamParser::EV_START_ELEMENT, "root");
196 p.attribute<int>("a");
197 assertTrue (false);
198 }
199 catch (const Poco::Exception&)
200 {
201 // cerr << e.what () << endl;
202 }
203
204 // Test peeking and getting the current event.
205 //
206 {
207 std::istringstream is("<root x='x'>x<nested/></root>");
208 XMLStreamParser p(is, "peek", XMLStreamParser::RECEIVE_DEFAULT | XMLStreamParser::RECEIVE_ATTRIBUTES_EVENT);
209
210 assertTrue (p.event() == XMLStreamParser::EV_EOF);
211
212 assertTrue (p.peek() == XMLStreamParser::EV_START_ELEMENT);
213 assertTrue (p.next() == XMLStreamParser::EV_START_ELEMENT);
214 assertTrue (p.event() == XMLStreamParser::EV_START_ELEMENT);
215
216 assertTrue (p.peek() == XMLStreamParser::EV_START_ATTRIBUTE);
217 assertTrue (p.event() == XMLStreamParser::EV_START_ATTRIBUTE);
218 assertTrue (p.next() == XMLStreamParser::EV_START_ATTRIBUTE);
219
220 assertTrue (p.peek() == XMLStreamParser::EV_CHARACTERS && p.value() == "x");
221 assertTrue (p.next() == XMLStreamParser::EV_CHARACTERS && p.value() == "x");
222 assertTrue (p.event() == XMLStreamParser::EV_CHARACTERS && p.value() == "x");
223
224 assertTrue (p.peek() == XMLStreamParser::EV_END_ATTRIBUTE);
225 assertTrue (p.event() == XMLStreamParser::EV_END_ATTRIBUTE);
226 assertTrue (p.next() == XMLStreamParser::EV_END_ATTRIBUTE);
227
228 assertTrue (p.peek() == XMLStreamParser::EV_CHARACTERS && p.value() == "x");
229 assertTrue (p.next() == XMLStreamParser::EV_CHARACTERS && p.value() == "x");
230 assertTrue (p.event() == XMLStreamParser::EV_CHARACTERS && p.value() == "x");
231
232 assertTrue (p.peek() == XMLStreamParser::EV_START_ELEMENT);
233 assertTrue (p.next() == XMLStreamParser::EV_START_ELEMENT);
234 assertTrue (p.event() == XMLStreamParser::EV_START_ELEMENT);
235
236 assertTrue (p.peek() == XMLStreamParser::EV_END_ELEMENT);
237 assertTrue (p.next() == XMLStreamParser::EV_END_ELEMENT);
238 assertTrue (p.event() == XMLStreamParser::EV_END_ELEMENT);
239
240 assertTrue (p.peek() == XMLStreamParser::EV_END_ELEMENT);
241 assertTrue (p.next() == XMLStreamParser::EV_END_ELEMENT);
242 assertTrue (p.event() == XMLStreamParser::EV_END_ELEMENT);
243
244 assertTrue (p.peek() == XMLStreamParser::EV_EOF);
245 assertTrue (p.next() == XMLStreamParser::EV_EOF);
246 assertTrue (p.event() == XMLStreamParser::EV_EOF);
247 }
248
249 // Test content processing.
250 //
251
252 // empty
253 //
254 {
255 std::istringstream is("<root x=' x '> \n\t </root>");
256 XMLStreamParser p(is, "empty", XMLStreamParser::RECEIVE_DEFAULT | XMLStreamParser::RECEIVE_ATTRIBUTES_EVENT);
257
258 assertTrue (p.next() == XMLStreamParser::EV_START_ELEMENT);
259 p.content(Content::Empty);
260 assertTrue (p.next() == XMLStreamParser::EV_START_ATTRIBUTE);
261 assertTrue (p.next() == XMLStreamParser::EV_CHARACTERS && p.value() == " x ");
262 assertTrue (p.next() == XMLStreamParser::EV_END_ATTRIBUTE);
263 assertTrue (p.next() == XMLStreamParser::EV_END_ELEMENT);
264 assertTrue (p.next() == XMLStreamParser::EV_EOF);
265 }
266
267 try
268 {
269 std::istringstream is("<root> \n &amp; X \t </root>");
270 XMLStreamParser p(is, "empty");
271
272 assertTrue (p.next() == XMLStreamParser::EV_START_ELEMENT);
273 p.content(Content::Empty);
274 p.next();
275 assertTrue (false);
276 }
277 catch (const Poco::Exception&)
278 {
279 // cerr << e.what () << endl;
280 }
281
282 // simple
283 //
284 {
285 std::istringstream is("<root> X </root>");
286 XMLStreamParser p(is, "simple");
287
288 assertTrue (p.next() == XMLStreamParser::EV_START_ELEMENT);
289 p.content(Content::Simple);
290 assertTrue (p.next() == XMLStreamParser::EV_CHARACTERS && p.value() == " X ");
291 assertTrue (p.next() == XMLStreamParser::EV_END_ELEMENT);
292 assertTrue (p.next() == XMLStreamParser::EV_EOF);
293 }
294
295 try
296 {
297 std::istringstream is("<root> ? <nested/></root>");
298 XMLStreamParser p(is, "simple");
299
300 assertTrue (p.next() == XMLStreamParser::EV_START_ELEMENT);
301 p.content(Content::Simple);
302 assertTrue (p.next() == XMLStreamParser::EV_CHARACTERS && p.value() == " ? ");
303 p.next();
304 assertTrue (false);
305 }
306 catch (const Poco::Exception&)
307 {
308 // cerr << e.what () << endl;
309 }
310
311 {
312 // Test content accumulation in simple content.
313 //
314 std::istringstream is("<root xmlns:a='a'>1&#x32;3</root>");
315 XMLStreamParser p(is, "simple", XMLStreamParser::RECEIVE_DEFAULT | XMLStreamParser::RECEIVE_NAMESPACE_DECLS);
316
317 assertTrue (p.next() == XMLStreamParser::EV_START_ELEMENT);
318 p.nextExpect(XMLStreamParser::EV_START_NAMESPACE_DECL);
319 p.content(Content::Simple);
320 assertTrue (p.next() == XMLStreamParser::EV_CHARACTERS && p.value() == "123");
321 p.nextExpect(XMLStreamParser::EV_END_NAMESPACE_DECL);
322 assertTrue (p.next() == XMLStreamParser::EV_END_ELEMENT);
323 assertTrue (p.next() == XMLStreamParser::EV_EOF);
324 }
325
326 try
327 {
328 // Test error handling in accumulation in simple content.
329 //
330 std::istringstream is("<root xmlns:a='a'>1&#x32;<nested/>3</root>");
331 XMLStreamParser p(is, "simple", XMLStreamParser::RECEIVE_DEFAULT | XMLStreamParser::RECEIVE_NAMESPACE_DECLS);
332
333 assertTrue (p.next() == XMLStreamParser::EV_START_ELEMENT);
334 p.nextExpect(XMLStreamParser::EV_START_NAMESPACE_DECL);
335 p.content(Content::Simple);
336 p.next();
337 assertTrue (false);
338 }
339 catch (const Poco::Exception&)
340 {
341 // cerr << e.what () << endl;
342 }
343
344 // complex
345 //
346 {
347 std::istringstream is("<root x=' x '>\n"
348 " <nested>\n"
349 " <inner/>\n"
350 " <inner> X </inner>\n"
351 " </nested>\n"
352 "</root>\n");
353 XMLStreamParser p(is, "complex", XMLStreamParser::RECEIVE_DEFAULT | XMLStreamParser::RECEIVE_ATTRIBUTES_EVENT);
354
355 assertTrue (p.next() == XMLStreamParser::EV_START_ELEMENT); // root
356 p.content(Content::Complex);
357
358 assertTrue (p.next() == XMLStreamParser::EV_START_ATTRIBUTE);
359 assertTrue (p.next() == XMLStreamParser::EV_CHARACTERS && p.value() == " x ");
360 assertTrue (p.next() == XMLStreamParser::EV_END_ATTRIBUTE);
361
362 assertTrue (p.next() == XMLStreamParser::EV_START_ELEMENT); // nested
363 p.content(Content::Complex);
364
365 assertTrue (p.next() == XMLStreamParser::EV_START_ELEMENT); // inner
366 p.content(Content::Empty);
367 assertTrue (p.next() == XMLStreamParser::EV_END_ELEMENT); // inner
368
369 assertTrue (p.next() == XMLStreamParser::EV_START_ELEMENT); // inner
370 p.content(Content::Simple);
371 assertTrue (p.next() == XMLStreamParser::EV_CHARACTERS && p.value() == " X ");
372 assertTrue (p.next() == XMLStreamParser::EV_END_ELEMENT); // inner
373
374 assertTrue (p.next() == XMLStreamParser::EV_END_ELEMENT); // nested
375 assertTrue (p.next() == XMLStreamParser::EV_END_ELEMENT); // root
376 assertTrue (p.next() == XMLStreamParser::EV_EOF);
377 }
378
379 try
380 {
381 std::istringstream is("<root> \n<n/> X <n> X </n> </root>");
382 XMLStreamParser p(is, "complex");
383
384 assertTrue (p.next() == XMLStreamParser::EV_START_ELEMENT);
385 p.content(Content::Complex);
386 assertTrue (p.next() == XMLStreamParser::EV_START_ELEMENT);
387 assertTrue (p.next() == XMLStreamParser::EV_END_ELEMENT);
388 p.next();
389 assertTrue (false);
390 }
391 catch (const Poco::Exception&)
392 {
393 // cerr << e.what () << endl;
394 }
395
396 // Test element with simple content helpers.
397 //
398 {
399 std::istringstream is("<root>"
400 " <nested>X</nested>"
401 " <nested/>"
402 " <nested>123</nested>"
403 " <nested>Y</nested>"
404 " <t:nested xmlns:t='test'>Z</t:nested>"
405 " <nested>234</nested>"
406 " <t:nested xmlns:t='test'>345</t:nested>"
407 " <nested>A</nested>"
408 " <t:nested xmlns:t='test'>B</t:nested>"
409 " <nested1>A</nested1>"
410 " <t:nested1 xmlns:t='test'>B</t:nested1>"
411 " <nested>1</nested>"
412 " <t:nested xmlns:t='test'>2</t:nested>"
413 " <nested1>1</nested1>"
414 " <t:nested1 xmlns:t='test'>2</t:nested1>"
415 "</root>");
416 XMLStreamParser p(is, "element");
417
418 p.nextExpect(XMLStreamParser::EV_START_ELEMENT, "root", Content::Complex);
419
420 p.nextExpect(XMLStreamParser::EV_START_ELEMENT, "nested");
421 assertTrue (p.element() == "X");
422
423 p.nextExpect(XMLStreamParser::EV_START_ELEMENT, "nested");
424 assertTrue (p.element() == "");
425
426 p.nextExpect(XMLStreamParser::EV_START_ELEMENT, "nested");
427 assertTrue (p.element<unsigned int>() == 123);
428
429 assertTrue (p.element("nested") == "Y");
430 assertTrue (p.element(QName("test", "nested")) == "Z");
431
432 assertTrue (p.element<unsigned int>("nested") == 234);
433 assertTrue (p.element<unsigned int>(QName("test", "nested")) == 345);
434
435 assertTrue (p.element("nested", "a") == "A");
436 assertTrue (p.element(QName("test", "nested"), "b") == "B");
437
438 assertTrue (p.element("nested", "a") == "a" && p.element("nested1") == "A");
439 assertTrue (p.element(QName("test", "nested"), "b") == "b" && p.element(QName("test", "nested1")) == "B");
440
441 assertTrue (p.element<unsigned int>("nested", 10) == 1);
442 assertTrue (p.element<unsigned int>(QName("test", "nested"), 20) == 2);
443
444 assertTrue (p.element<unsigned int>("nested", 10) == 10 && p.element<unsigned int>("nested1") == 1);
445 assertTrue (p.element<unsigned int>(QName("test", "nested"), 20) == 20 && p.element<unsigned int>(QName("test", "nested1")) == 2);
446
447 p.nextExpect(XMLStreamParser::EV_END_ELEMENT);
448 }
449
450 // Test the iterator interface.
451 //
452 {
453 std::istringstream is("<root><nested>X</nested></root>");
454 XMLStreamParser p(is, "iterator");
455
456 std::vector<XMLStreamParser::EventType> v;
457
458 for (XMLStreamParser::Iterator i(p.begin()); i != p.end(); ++i)
459 v.push_back(*i);
460
461 //for (XMLStreamParser::EventType e: p)
462 // v.push_back (e);
463
464 assertTrue (v.size() == 5);
465 assertTrue (v[0] == XMLStreamParser::EV_START_ELEMENT);
466 assertTrue (v[1] == XMLStreamParser::EV_START_ELEMENT);
467 assertTrue (v[2] == XMLStreamParser::EV_CHARACTERS);
468 assertTrue (v[3] == XMLStreamParser::EV_END_ELEMENT);
469 assertTrue (v[4] == XMLStreamParser::EV_END_ELEMENT);
470 }
471
472 // Test space extraction into the std::string value.
473 //
474 {
475 std::istringstream is("<root a=' a '> b </root>");
476 XMLStreamParser p(is, "test");
477 p.nextExpect(XMLStreamParser::EV_START_ELEMENT, "root");
478 assertTrue (p.attribute<std::string>("a") == " a ");
479 p.nextExpect(XMLStreamParser::EV_CHARACTERS);
480 assertTrue (p.value<std::string>() == " b ");
481 p.nextExpect(XMLStreamParser::EV_END_ELEMENT);
482 }
483}
484
485
486void XMLStreamParserTest::setUp()
487{
488}
489
490
491void XMLStreamParserTest::tearDown()
492{
493}
494
495
496CppUnit::Test* XMLStreamParserTest::suite()
497{
498 CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("XMLStreamParserTest");
499
500 CppUnit_addTest(pSuite, XMLStreamParserTest, testParser);
501
502 return pSuite;
503}
504