1014d474284482e6b998cf6b4a75255370635daa
1 /**
2 * Phoebe DOM Implementation.
3 *
4 * This is a C++ approximation of the W3C DOM model, which follows
5 * fairly closely the specifications in the various .idl files, copies of
6 * which are provided for reference. Most important is this one:
7 *
8 * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html
9 *
10 * Authors:
11 * Bob Jamison
12 *
13 * Copyright (C) 2006-2008 Bob Jamison
14 *
15 * This library is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU Lesser General Public
17 * License as published by the Free Software Foundation; either
18 * version 2.1 of the License, or (at your option) any later version.
19 *
20 * This library is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * Lesser General Public License for more details.
24 *
25 * You should have received a copy of the GNU Lesser General Public
26 * License along with this library; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */
32 #include "dom.h"
33 #include "lsimpl.h"
34 #include "xpathparser.h"
36 #include <stdio.h>
39 typedef org::w3c::dom::Node Node;
40 typedef org::w3c::dom::NodePtr NodePtr;
41 typedef org::w3c::dom::NodeList NodeList;
42 typedef org::w3c::dom::DOMString DOMString;
43 typedef org::w3c::dom::Document Document;
44 typedef org::w3c::dom::DocumentPtr DocumentPtr;
45 typedef org::w3c::dom::io::StdWriter StdWriter;
46 typedef org::w3c::dom::ls::DOMImplementationLSImpl DOMImplementationLSImpl;
47 typedef org::w3c::dom::ls::LSSerializer LSSerializer;
48 typedef org::w3c::dom::ls::LSOutput LSOutput;
49 typedef org::w3c::dom::ls::LSInput LSInput;
50 typedef org::w3c::dom::ls::LSParser LSParser;
51 typedef org::w3c::dom::xpath::XPathParser XPathParser;
55 typedef struct
56 {
57 const char *xpathStr;
58 const char *desc;
59 const char *xml;
60 } XpathTest;
62 XpathTest xpathTests[] =
63 {
65 {
66 "/AAA",
67 "Select the root element AAA",
68 " <AAA>\n"
69 " <BBB/>\n"
70 " <CCC/>\n"
71 " <BBB/>\n"
72 " <BBB/>\n"
73 " <DDD>\n"
74 " <BBB/>\n"
75 " </DDD>\n"
76 " <CCC/>\n"
77 " </AAA>\n"
78 },
80 {
81 "/AAA/CCC",
82 "Select all elements CCC which are children of the root element AAA",
83 " <AAA>\n"
84 " <BBB/>\n"
85 " <CCC/>\n"
86 " <BBB/>\n"
87 " <BBB/>\n"
88 " <DDD>\n"
89 " <BBB/>\n"
90 " </DDD>\n"
91 " <CCC/>\n"
92 " </AAA>\n"
93 },
95 {
96 "/AAA/DDD/BBB",
97 "Select all elements BBB which are children of DDD which are children of the root element AAA",
98 " <AAA>\n"
99 " <BBB/>\n"
100 " <CCC/>\n"
101 " <BBB/>\n"
102 " <BBB/>\n"
103 " <DDD>\n"
104 " <BBB/>\n"
105 " </DDD>\n"
106 " <CCC/>\n"
107 " </AAA>\n"
108 },
110 {
111 "//BBB",
112 "Select all elements BBB",
113 " <AAA>\n"
114 " <BBB/>\n"
115 " <CCC/>\n"
116 " <BBB/>\n"
117 " <DDD>\n"
118 " <BBB/>\n"
119 " </DDD>\n"
120 " <CCC>\n"
121 " <DDD>\n"
122 " <BBB/>\n"
123 " <BBB/>\n"
124 " </DDD>\n"
125 " </CCC>\n"
126 " </AAA>\n"
127 },
129 {
130 "//DDD/BBB",
131 "Select all elements BBB which are children of DDD",
132 " <AAA>\n"
133 " <BBB/>\n"
134 " <CCC/>\n"
135 " <BBB/>\n"
136 " <DDD>\n"
137 " <BBB/>\n"
138 " </DDD>\n"
139 " <CCC>\n"
140 " <DDD>\n"
141 " <BBB/>\n"
142 " <BBB/>\n"
143 " </DDD>\n"
144 " </CCC>\n"
145 " </AAA>\n"
146 },
148 {
149 "/AAA/CCC/DDD/*",
150 "Select all elements enclosed by elements /AAA/CCC/DDD",
151 " <AAA>\n"
152 " <XXX>\n"
153 " <DDD>\n"
154 " <BBB/>\n"
155 " <BBB/>\n"
156 " <EEE/>\n"
157 " <FFF/>\n"
158 " </DDD>\n"
159 " </XXX>\n"
160 " <CCC>\n"
161 " <DDD>\n"
162 " <BBB/>\n"
163 " <BBB/>\n"
164 " <EEE/>\n"
165 " <FFF/>\n"
166 " </DDD>\n"
167 " </CCC>\n"
168 " <CCC>\n"
169 " <BBB>\n"
170 " <BBB>\n"
171 " <BBB/>\n"
172 " </BBB>\n"
173 " </BBB>\n"
174 " </CCC>\n"
175 " </AAA>\n"
176 },
178 {
179 "/*/*/*/BBB",
180 "Select all elements BBB which have 3 ancestors",
181 " <AAA>\n"
182 " <XXX>\n"
183 " <DDD>\n"
184 " <BBB/>\n"
185 " <BBB/>\n"
186 " <EEE/>\n"
187 " <FFF/>\n"
188 " </DDD>\n"
189 " </XXX>\n"
190 " <CCC>\n"
191 " <DDD>\n"
192 " <BBB/>\n"
193 " <BBB/>\n"
194 " <EEE/>\n"
195 " <FFF/>\n"
196 " </DDD>\n"
197 " </CCC>\n"
198 " <CCC>\n"
199 " <BBB>\n"
200 " <BBB>\n"
201 " <BBB/>\n"
202 " </BBB>\n"
203 " </BBB>\n"
204 " </CCC>\n"
205 " </AAA>\n"
206 },
208 {
209 "//*",
210 "Select all elements",
211 " <AAA>\n"
212 " <XXX>\n"
213 " <DDD>\n"
214 " <BBB/>\n"
215 " <BBB/>\n"
216 " <EEE/>\n"
217 " <FFF/>\n"
218 " </DDD>\n"
219 " </XXX>\n"
220 " <CCC>\n"
221 " <DDD>\n"
222 " <BBB/>\n"
223 " <BBB/>\n"
224 " <EEE/>\n"
225 " <FFF/>\n"
226 " </DDD>\n"
227 " </CCC>\n"
228 " <CCC>\n"
229 " <BBB>\n"
230 " <BBB>\n"
231 " <BBB/>\n"
232 " </BBB>\n"
233 " </BBB>\n"
234 " </CCC>\n"
235 " </AAA>\n"
236 },
238 {
239 "/AAA/BBB[1]",
240 "Select the first BBB child of element AAA",
241 " <AAA>\n"
242 " <BBB/>\n"
243 " <BBB/>\n"
244 " <BBB/>\n"
245 " <BBB/>\n"
246 " </AAA>\n"
247 },
249 {
250 "/AAA/BBB[last()]",
251 "Select the last BBB child of element AAA",
252 " <AAA>\n"
253 " <BBB/>\n"
254 " <BBB/>\n"
255 " <BBB/>\n"
256 " <BBB/>\n"
257 " </AAA>\n"
258 },
260 {
261 "//@id",
262 "Select all attributes @id",
263 " <AAA>\n"
264 " <BBB id = 'b1'/>\n"
265 " <BBB id = 'b2'/>\n"
266 " <BBB name = 'bbb'/>\n"
267 " <BBB/>\n"
268 " </AAA>\n"
269 },
271 {
272 "//BBB[@id]",
273 "Select BBB elements which have attribute id",
274 " <AAA>\n"
275 " <BBB id = 'b1'/>\n"
276 " <BBB id = 'b2'/>\n"
277 " <BBB name = 'bbb'/>\n"
278 " <BBB/>\n"
279 " </AAA>\n"
280 },
282 {
283 "//BBB[@name]",
284 "Select BBB elements which have attribute name",
285 " <AAA>\n"
286 " <BBB id = 'b1'/>\n"
287 " <BBB id = 'b2'/>\n"
288 " <BBB name = 'bbb'/>\n"
289 " <BBB/>\n"
290 " </AAA>\n"
291 },
293 {
294 "//BBB[@*]",
295 "Select BBB elements which have any attribute",
296 " <AAA>\n"
297 " <BBB id = 'b1'/>\n"
298 " <BBB id = 'b2'/>\n"
299 " <BBB name = 'bbb'/>\n"
300 " <BBB/>\n"
301 " </AAA>\n"
302 },
304 {
305 "//BBB[not(@*)]",
306 "Select BBB elements without an attribute",
307 " <AAA>\n"
308 " <BBB id = 'b1'/>\n"
309 " <BBB id = 'b2'/>\n"
310 " <BBB name = 'bbb'/>\n"
311 " <BBB/>\n"
312 " </AAA>\n"
313 },
315 {
316 "//BBB[@id='b1']",
317 "Select BBB elements which have attribute id with value b1",
318 " <AAA>\n"
319 " <BBB id = 'b1'/>\n"
320 " <BBB name = ' bbb '/>\n"
321 " <BBB name = 'bbb'/>\n"
322 " </AAA>\n"
323 },
325 {
326 "//BBB[@name='bbb']",
327 "Select BBB elements which have attribute name with value 'bbb'",
328 " <AAA>\n"
329 " <BBB id = 'b1'/>\n"
330 " <BBB name = ' bbb '/>\n"
331 " <BBB name = 'bbb'/>\n"
332 " </AAA>\n"
333 },
335 {
336 "//BBB[normalize-space(@name)='bbb']",
337 "Select BBB elements which have attribute name with value bbb, leading and trailing spaces are removed before comparison",
338 " <AAA>\n"
339 " <BBB id = 'b1'/>\n"
340 " <BBB name = ' bbb '/>\n"
341 " <BBB name = 'bbb'/>\n"
342 " </AAA>\n"
343 },
345 {
346 "//*[count(BBB)=2]",
347 "Select elements which have two children BBB",
348 " <AAA>\n"
349 " <CCC>\n"
350 " <BBB/>\n"
351 " <BBB/>\n"
352 " <BBB/>\n"
353 " </CCC>\n"
354 " <DDD>\n"
355 " <BBB/>\n"
356 " <BBB/>\n"
357 " </DDD>\n"
358 " <EEE>\n"
359 " <CCC/>\n"
360 " <DDD/>\n"
361 " </EEE>\n"
362 " </AAA>\n"
363 },
365 {
366 "//*[count(*)=2]",
367 "Select elements which have 2 children",
368 " <AAA>\n"
369 " <CCC>\n"
370 " <BBB/>\n"
371 " <BBB/>\n"
372 " <BBB/>\n"
373 " </CCC>\n"
374 " <DDD>\n"
375 " <BBB/>\n"
376 " <BBB/>\n"
377 " </DDD>\n"
378 " <EEE>\n"
379 " <CCC/>\n"
380 " <DDD/>\n"
381 " </EEE>\n"
382 " </AAA>\n"
383 },
385 {
386 "//*[count(*)=3]",
387 "Select elements which have 3 children",
388 " <AAA>\n"
389 " <CCC>\n"
390 " <BBB/>\n"
391 " <BBB/>\n"
392 " <BBB/>\n"
393 " </CCC>\n"
394 " <DDD>\n"
395 " <BBB/>\n"
396 " <BBB/>\n"
397 " </DDD>\n"
398 " <EEE>\n"
399 " <CCC/>\n"
400 " <DDD/>\n"
401 " </EEE>\n"
402 " </AAA>\n"
403 },
405 {
406 "//*[name()='BBB']",
407 "Select all elements with name BBB, equivalent with //BBB",
408 " <AAA>\n"
409 " <BCC>\n"
410 " <BBB/>\n"
411 " <BBB/>\n"
412 " <BBB/>\n"
413 " </BCC>\n"
414 " <DDB>\n"
415 " <BBB/>\n"
416 " <BBB/>\n"
417 " </DDB>\n"
418 " <BEC>\n"
419 " <CCC/>\n"
420 " <DBD/>\n"
421 " </BEC>\n"
422 " </AAA>\n"
423 },
425 {
426 "//*[starts-with(name(),'B')]",
427 "Select all elements name of which starts with letter B",
428 " <AAA>\n"
429 " <BCC>\n"
430 " <BBB/>\n"
431 " <BBB/>\n"
432 " <BBB/>\n"
433 " </BCC>\n"
434 " <DDB>\n"
435 " <BBB/>\n"
436 " <BBB/>\n"
437 " </DDB>\n"
438 " <BEC>\n"
439 " <CCC/>\n"
440 " <DBD/>\n"
441 " </BEC>\n"
442 " </AAA>\n"
443 },
445 {
446 "//*[contains(name(),'C')]",
447 "Select all elements name of which contain letter C",
448 " <AAA>\n"
449 " <BCC>\n"
450 " <BBB/>\n"
451 " <BBB/>\n"
452 " <BBB/>\n"
453 " </BCC>\n"
454 " <DDB>\n"
455 " <BBB/>\n"
456 " <BBB/>\n"
457 " </DDB>\n"
458 " <BEC>\n"
459 " <CCC/>\n"
460 " <DBD/>\n"
461 " </BEC>\n"
462 " </AAA>\n"
463 },
465 {
466 "//*[string-length(name()) = 3]",
467 "Select elements with three-letter name",
468 " <AAA>\n"
469 " <Q/>\n"
470 " <SSSS/>\n"
471 " <BB/>\n"
472 " <CCC/>\n"
473 " <DDDDDDDD/>\n"
474 " <EEEE/>\n"
475 " </AAA>\n"
476 },
478 {
479 "//*[string-length(name()) < 3]",
480 "Select elements name of which has one or two characters",
481 " <AAA>\n"
482 " <Q/>\n"
483 " <SSSS/>\n"
484 " <BB/>\n"
485 " <CCC/>\n"
486 " <DDDDDDDD/>\n"
487 " <EEEE/>\n"
488 " </AAA>\n"
489 },
491 {
492 "//*[string-length(name()) > 3]",
493 "Select elements with name longer than three characters",
494 " <AAA>\n"
495 " <Q/>\n"
496 " <SSSS/>\n"
497 " <BB/>\n"
498 " <CCC/>\n"
499 " <DDDDDDDD/>\n"
500 " <EEEE/>\n"
501 " </AAA>\n"
502 },
504 {
505 "//CCC | //BBB",
506 "Select all elements CCC and BBB",
507 " <AAA>\n"
508 " <BBB/>\n"
509 " <CCC/>\n"
510 " <DDD>\n"
511 " <CCC/>\n"
512 " </DDD>\n"
513 " <EEE/>\n"
514 " </AAA>\n"
515 },
517 {
518 "/AAA/EEE | //BBB",
519 "Select all elements BBB and elements EEE which are children of root element AAA",
520 " <AAA>\n"
521 " <BBB/>\n"
522 " <CCC/>\n"
523 " <DDD>\n"
524 " <CCC/>\n"
525 " </DDD>\n"
526 " <EEE/>\n"
527 " </AAA>\n"
528 },
530 {
531 "/AAA/EEE | //DDD/CCC | /AAA | //BBB",
532 "Number of combinations is not restricted",
533 " <AAA>\n"
534 " <BBB/>\n"
535 " <CCC/>\n"
536 " <DDD>\n"
537 " <CCC/>\n"
538 " </DDD>\n"
539 " <EEE/>\n"
540 " </AAA>\n"
541 },
543 {
544 "/AAA",
545 "Equivalent of /child::AAA",
546 " <AAA>\n"
547 " <BBB/>\n"
548 " <CCC/>\n"
549 " </AAA>\n"
550 },
552 {
553 "/child::AAA",
554 "Equivalent of /AAA",
555 " <AAA>\n"
556 " <BBB/>\n"
557 " <CCC/>\n"
558 " </AAA>\n"
559 },
561 {
562 "/AAA/BBB",
563 "Equivalent of /child::AAA/child::BBB",
564 " <AAA>\n"
565 " <BBB/>\n"
566 " <CCC/>\n"
567 " </AAA>\n"
568 },
570 {
571 "/child::AAA/child::BBB",
572 "Equivalent of /AAA/BBB",
573 " <AAA>\n"
574 " <BBB/>\n"
575 " <CCC/>\n"
576 " </AAA>\n"
577 },
579 {
580 "/child::AAA/BBB",
581 "Both possibilities can be combined",
582 " <AAA>\n"
583 " <BBB/>\n"
584 " <CCC/>\n"
585 " </AAA>\n"
586 },
588 {
589 "/descendant::*",
590 "Select all descendants of document root and therefore all elements",
591 " <AAA>\n"
592 " <BBB>\n"
593 " <DDD>\n"
594 " <CCC>\n"
595 " <DDD/>\n"
596 " <EEE/>\n"
597 " </CCC>\n"
598 " </DDD>\n"
599 " </BBB>\n"
600 " <CCC>\n"
601 " <DDD>\n"
602 " <EEE>\n"
603 " <DDD>\n"
604 " <FFF/>\n"
605 " </DDD>\n"
606 " </EEE>\n"
607 " </DDD>\n"
608 " </CCC>\n"
609 " </AAA>\n"
610 },
612 {
613 "/AAA/BBB/descendant::*",
614 "Select all descendants of /AAA/BBB",
615 " <AAA>\n"
616 " <BBB>\n"
617 " <DDD>\n"
618 " <CCC>\n"
619 " <DDD/>\n"
620 " <EEE/>\n"
621 " </CCC>\n"
622 " </DDD>\n"
623 " </BBB>\n"
624 " <CCC>\n"
625 " <DDD>\n"
626 " <EEE>\n"
627 " <DDD>\n"
628 " <FFF/>\n"
629 " </DDD>\n"
630 " </EEE>\n"
631 " </DDD>\n"
632 " </CCC>\n"
633 " </AAA>\n"
634 },
636 {
637 "//CCC/descendant::*",
638 "Select all elements which have CCC among its ancestors",
639 " <AAA>\n"
640 " <BBB>\n"
641 " <DDD>\n"
642 " <CCC>\n"
643 " <DDD/>\n"
644 " <EEE/>\n"
645 " </CCC>\n"
646 " </DDD>\n"
647 " </BBB>\n"
648 " <CCC>\n"
649 " <DDD>\n"
650 " <EEE>\n"
651 " <DDD>\n"
652 " <FFF/>\n"
653 " </DDD>\n"
654 " </EEE>\n"
655 " </DDD>\n"
656 " </CCC>\n"
657 " </AAA>\n"
658 },
660 {
661 "//CCC/descendant::DDD",
662 "Select elements DDD which have CCC among its ancestors",
663 " <AAA>\n"
664 " <BBB>\n"
665 " <DDD>\n"
666 " <CCC>\n"
667 " <DDD/>\n"
668 " <EEE/>\n"
669 " </CCC>\n"
670 " </DDD>\n"
671 " </BBB>\n"
672 " <CCC>\n"
673 " <DDD>\n"
674 " <EEE>\n"
675 " <DDD>\n"
676 " <FFF/>\n"
677 " </DDD>\n"
678 " </EEE>\n"
679 " </DDD>\n"
680 " </CCC>\n"
681 " </AAA>\n"
682 },
684 {
685 "//DDD/parent::*",
686 "Select all parents of DDD element",
687 " <AAA>\n"
688 " <BBB>\n"
689 " <DDD>\n"
690 " <CCC>\n"
691 " <DDD/>\n"
692 " <EEE/>\n"
693 " </CCC>\n"
694 " </DDD>\n"
695 " </BBB>\n"
696 " <CCC>\n"
697 " <DDD>\n"
698 " <EEE>\n"
699 " <DDD>\n"
700 " <FFF/>\n"
701 " </DDD>\n"
702 " </EEE>\n"
703 " </DDD>\n"
704 " </CCC>\n"
705 " </AAA>\n"
706 },
708 {
709 "/AAA/BBB/DDD/CCC/EEE/ancestor::*",
710 "Select all elements given in this absolute path",
711 " <AAA>\n"
712 " <BBB>\n"
713 " <DDD>\n"
714 " <CCC>\n"
715 " <DDD/>\n"
716 " <EEE/>\n"
717 " </CCC>\n"
718 " </DDD>\n"
719 " </BBB>\n"
720 " <CCC>\n"
721 " <DDD>\n"
722 " <EEE>\n"
723 " <DDD>\n"
724 " <FFF/>\n"
725 " </DDD>\n"
726 " </EEE>\n"
727 " </DDD>\n"
728 " </CCC>\n"
729 " </AAA>\n"
730 },
732 {
733 "//FFF/ancestor::*",
734 "Select ancestors of FFF element",
735 " <AAA>\n"
736 " <BBB>\n"
737 " <DDD>\n"
738 " <CCC>\n"
739 " <DDD/>\n"
740 " <EEE/>\n"
741 " </CCC>\n"
742 " </DDD>\n"
743 " </BBB>\n"
744 " <CCC>\n"
745 " <DDD>\n"
746 " <EEE>\n"
747 " <DDD>\n"
748 " <FFF/>\n"
749 " </DDD>\n"
750 " </EEE>\n"
751 " </DDD>\n"
752 " </CCC>\n"
753 " </AAA>\n"
754 },
756 {
757 "/AAA/BBB/following-sibling::*",
758 "The following-sibling axis contains all the following siblings of the context node.",
759 " <AAA>\n"
760 " <BBB>\n"
761 " <CCC/>\n"
762 " <DDD/>\n"
763 " </BBB>\n"
764 " <XXX>\n"
765 " <DDD>\n"
766 " <EEE/>\n"
767 " <DDD/>\n"
768 " <CCC/>\n"
769 " <FFF/>\n"
770 " <FFF>\n"
771 " <GGG/>\n"
772 " </FFF>\n"
773 " </DDD>\n"
774 " </XXX>\n"
775 " <CCC>\n"
776 " <DDD/>\n"
777 " </CCC>\n"
778 " </AAA>\n"
779 },
781 {
782 "//CCC/following-sibling::*",
783 "The following-sibling axis contains all the following siblings of the context node.",
784 " <AAA>\n"
785 " <BBB>\n"
786 " <CCC/>\n"
787 " <DDD/>\n"
788 " </BBB>\n"
789 " <XXX>\n"
790 " <DDD>\n"
791 " <EEE/>\n"
792 " <DDD/>\n"
793 " <CCC/>\n"
794 " <FFF/>\n"
795 " <FFF>\n"
796 " <GGG/>\n"
797 " </FFF>\n"
798 " </DDD>\n"
799 " </XXX>\n"
800 " <CCC>\n"
801 " <DDD/>\n"
802 " </CCC>\n"
803 " </AAA>\n"
804 },
806 {
807 "/AAA/XXX/preceding-sibling::*",
808 "The preceding-sibling axis contains all the preceding siblings of the context node.",
809 " <AAA>\n"
810 " <BBB>\n"
811 " <CCC/>\n"
812 " <DDD/>\n"
813 " </BBB>\n"
814 " <XXX>\n"
815 " <DDD>\n"
816 " <EEE/>\n"
817 " <DDD/>\n"
818 " <CCC/>\n"
819 " <FFF/>\n"
820 " <FFF>\n"
821 " <GGG/>\n"
822 " </FFF>\n"
823 " </DDD>\n"
824 " </XXX>\n"
825 " <CCC>\n"
826 " <DDD/>\n"
827 " </CCC>\n"
828 " </AAA>\n"
829 },
831 {
832 "//CCC/preceding-sibling::*",
833 "The preceding-sibling axis contains all the preceding siblings of the context node",
834 " <AAA>\n"
835 " <BBB>\n"
836 " <CCC/>\n"
837 " <DDD/>\n"
838 " </BBB>\n"
839 " <XXX>\n"
840 " <DDD>\n"
841 " <EEE/>\n"
842 " <DDD/>\n"
843 " <CCC/>\n"
844 " <FFF/>\n"
845 " <FFF>\n"
846 " <GGG/>\n"
847 " </FFF>\n"
848 " </DDD>\n"
849 " </XXX>\n"
850 " <CCC>\n"
851 " <DDD/>\n"
852 " </CCC>\n"
853 " </AAA>\n"
854 },
856 {
857 "/AAA/XXX/following::*",
858 "The following axis contains all nodes in the same document as the context "
859 "node that are after the context node in document order, "
860 "excluding any descendants and excluding attribute nodes and namespace nodes.",
861 " <AAA>\n"
862 " <BBB>\n"
863 " <CCC/>\n"
864 " <ZZZ>\n"
865 " <DDD/>\n"
866 " <DDD>\n"
867 " <EEE/>\n"
868 " </DDD>\n"
869 " </ZZZ>\n"
870 " <FFF>\n"
871 " <GGG/>\n"
872 " </FFF>\n"
873 " </BBB>\n"
874 " <XXX>\n"
875 " <DDD>\n"
876 " <EEE/>\n"
877 " <DDD/>\n"
878 " <CCC/>\n"
879 " <FFF/>\n"
880 " <FFF>\n"
881 " <GGG/>\n"
882 " </FFF>\n"
883 " </DDD>\n"
884 " </XXX>\n"
885 " <CCC>\n"
886 " <DDD/>\n"
887 " </CCC>\n"
888 " </AAA>\n"
889 },
891 {
892 "//ZZZ/following::*",
893 "The following axis contains all nodes in the same document as the context "
894 "node that are after the context node in document order, "
895 "excluding any descendants and excluding attribute nodes and namespace nodes.",
896 " <AAA>\n"
897 " <BBB>\n"
898 " <CCC/>\n"
899 " <ZZZ>\n"
900 " <DDD/>\n"
901 " <DDD>\n"
902 " <EEE/>\n"
903 " </DDD>\n"
904 " </ZZZ>\n"
905 " <FFF>\n"
906 " <GGG/>\n"
907 " </FFF>\n"
908 " </BBB>\n"
909 " <XXX>\n"
910 " <DDD>\n"
911 " <EEE/>\n"
912 " <DDD/>\n"
913 " <CCC/>\n"
914 " <FFF/>\n"
915 " <FFF>\n"
916 " <GGG/>\n"
917 " </FFF>\n"
918 " </DDD>\n"
919 " </XXX>\n"
920 " <CCC>\n"
921 " <DDD/>\n"
922 " </CCC>\n"
923 " </AAA>\n"
924 },
926 {
927 "/AAA/XXX/preceding::*",
928 "The preceding axis contains all nodes in the same document as the "
929 "context node that are before the context node in document order, "
930 "excluding any ancestors and excluding attribute nodes and namespace nodes",
931 " <AAA>\n"
932 " <BBB>\n"
933 " <CCC/>\n"
934 " <ZZZ>\n"
935 " <DDD/>\n"
936 " </ZZZ>\n"
937 " </BBB>\n"
938 " <XXX>\n"
939 " <DDD>\n"
940 " <EEE/>\n"
941 " <DDD/>\n"
942 " <CCC/>\n"
943 " <FFF/>\n"
944 " <FFF>\n"
945 " <GGG/>\n"
946 " </FFF>\n"
947 " </DDD>\n"
948 " </XXX>\n"
949 " <CCC>\n"
950 " <DDD/>\n"
951 " </CCC>\n"
952 " </AAA>\n"
953 },
955 {
956 "//GGG/preceding::*",
957 "The preceding axis contains all nodes in the same document as the "
958 "context node that are before the context node in document order, "
959 "excluding any ancestors and excluding attribute nodes and namespace nodes",
960 " <AAA>\n"
961 " <BBB>\n"
962 " <CCC/>\n"
963 " <ZZZ>\n"
964 " <DDD/>\n"
965 " </ZZZ>\n"
966 " </BBB>\n"
967 " <XXX>\n"
968 " <DDD>\n"
969 " <EEE/>\n"
970 " <DDD/>\n"
971 " <CCC/>\n"
972 " <FFF/>\n"
973 " <FFF>\n"
974 " <GGG/>\n"
975 " </FFF>\n"
976 " </DDD>\n"
977 " </XXX>\n"
978 " <CCC>\n"
979 " <DDD/>\n"
980 " </CCC>\n"
981 " </AAA>\n"
982 },
984 {
985 "/AAA/XXX/descendant-or-self::*",
986 "The descendant-or-self axis contains the "
987 "context node and the descendants of the context node",
988 " <AAA>\n"
989 " <BBB>\n"
990 " <CCC/>\n"
991 " <ZZZ>\n"
992 " <DDD/>\n"
993 " </ZZZ>\n"
994 " </BBB>\n"
995 " <XXX>\n"
996 " <DDD>\n"
997 " <EEE/>\n"
998 " <DDD/>\n"
999 " <CCC/>\n"
1000 " <FFF/>\n"
1001 " <FFF>\n"
1002 " <GGG/>\n"
1003 " </FFF>\n"
1004 " </DDD>\n"
1005 " </XXX>\n"
1006 " <CCC>\n"
1007 " <DDD/>\n"
1008 " </CCC>\n"
1009 " </AAA>\n"
1010 },
1012 {
1013 "//CCC/descendant-or-self::*",
1014 "The descendant-or-self axis contains the "
1015 "context node and the descendants of the context node",
1016 " <AAA>\n"
1017 " <BBB>\n"
1018 " <CCC/>\n"
1019 " <ZZZ>\n"
1020 " <DDD/>\n"
1021 " </ZZZ>\n"
1022 " </BBB>\n"
1023 " <XXX>\n"
1024 " <DDD>\n"
1025 " <EEE/>\n"
1026 " <DDD/>\n"
1027 " <CCC/>\n"
1028 " <FFF/>\n"
1029 " <FFF>\n"
1030 " <GGG/>\n"
1031 " </FFF>\n"
1032 " </DDD>\n"
1033 " </XXX>\n"
1034 " <CCC>\n"
1035 " <DDD/>\n"
1036 " </CCC>\n"
1037 " </AAA>\n"
1038 },
1040 {
1041 "/AAA/XXX/DDD/EEE/ancestor-or-self::*",
1042 "The ancestor-or-self axis contains the context node and the "
1043 "ancestors of the context node; thus, the ancestor-or-self axis "
1044 "will always include the root node.",
1045 " <AAA>\n"
1046 " <BBB>\n"
1047 " <CCC/>\n"
1048 " <ZZZ>\n"
1049 " <DDD/>\n"
1050 " </ZZZ>\n"
1051 " </BBB>\n"
1052 " <XXX>\n"
1053 " <DDD>\n"
1054 " <EEE/>\n"
1055 " <DDD/>\n"
1056 " <CCC/>\n"
1057 " <FFF/>\n"
1058 " <FFF>\n"
1059 " <GGG/>\n"
1060 " </FFF>\n"
1061 " </DDD>\n"
1062 " </XXX>\n"
1063 " <CCC>\n"
1064 " <DDD/>\n"
1065 " </CCC>\n"
1066 " </AAA>\n"
1067 },
1069 {
1070 "//GGG/ancestor-or-self::*",
1071 "The ancestor-or-self axis contains the context node and the "
1072 "ancestors of the context node; thus, the ancestor-or-self axis "
1073 "will always include the root node.",
1074 " <AAA>\n"
1075 " <BBB>\n"
1076 " <CCC/>\n"
1077 " <ZZZ>\n"
1078 " <DDD/>\n"
1079 " </ZZZ>\n"
1080 " </BBB>\n"
1081 " <XXX>\n"
1082 " <DDD>\n"
1083 " <EEE/>\n"
1084 " <DDD/>\n"
1085 " <CCC/>\n"
1086 " <FFF/>\n"
1087 " <FFF>\n"
1088 " <GGG/>\n"
1089 " </FFF>\n"
1090 " </DDD>\n"
1091 " </XXX>\n"
1092 " <CCC>\n"
1093 " <DDD/>\n"
1094 " </CCC>\n"
1095 " </AAA>\n"
1096 },
1098 {
1099 "//GGG/ancestor::*",
1100 "The ancestor, descendant, following, preceding and self axes partition a document",
1101 " <AAA>\n"
1102 " <BBB>\n"
1103 " <CCC/>\n"
1104 " <ZZZ/>\n"
1105 " </BBB>\n"
1106 " <XXX>\n"
1107 " <DDD>\n"
1108 " <EEE/>\n"
1109 " <FFF>\n"
1110 " <HHH/>\n"
1111 " <GGG>\n"
1112 " <JJJ>\n"
1113 " <QQQ/>\n"
1114 " </JJJ>\n"
1115 " <JJJ/>\n"
1116 " </GGG>\n"
1117 " <HHH/>\n"
1118 " </FFF>\n"
1119 " </DDD>\n"
1120 " </XXX>\n"
1121 " <CCC>\n"
1122 " <DDD/>\n"
1123 " </CCC>\n"
1124 " </AAA>\n"
1125 },
1127 {
1128 "//GGG/descendant::*",
1129 "The ancestor, descendant, following, preceding and self axes partition a document",
1130 " <AAA>\n"
1131 " <BBB>\n"
1132 " <CCC/>\n"
1133 " <ZZZ/>\n"
1134 " </BBB>\n"
1135 " <XXX>\n"
1136 " <DDD>\n"
1137 " <EEE/>\n"
1138 " <FFF>\n"
1139 " <HHH/>\n"
1140 " <GGG>\n"
1141 " <JJJ>\n"
1142 " <QQQ/>\n"
1143 " </JJJ>\n"
1144 " <JJJ/>\n"
1145 " </GGG>\n"
1146 " <HHH/>\n"
1147 " </FFF>\n"
1148 " </DDD>\n"
1149 " </XXX>\n"
1150 " <CCC>\n"
1151 " <DDD/>\n"
1152 " </CCC>\n"
1153 " </AAA>\n"
1154 },
1156 {
1157 "//GGG/following::*",
1158 "The ancestor, descendant, following, preceding and self axes partition a document",
1159 " <AAA>\n"
1160 " <BBB>\n"
1161 " <CCC/>\n"
1162 " <ZZZ/>\n"
1163 " </BBB>\n"
1164 " <XXX>\n"
1165 " <DDD>\n"
1166 " <EEE/>\n"
1167 " <FFF>\n"
1168 " <HHH/>\n"
1169 " <GGG>\n"
1170 " <JJJ>\n"
1171 " <QQQ/>\n"
1172 " </JJJ>\n"
1173 " <JJJ/>\n"
1174 " </GGG>\n"
1175 " <HHH/>\n"
1176 " </FFF>\n"
1177 " </DDD>\n"
1178 " </XXX>\n"
1179 " <CCC>\n"
1180 " <DDD/>\n"
1181 " </CCC>\n"
1182 " </AAA>\n"
1183 },
1185 {
1186 "//GGG/preceding::*",
1187 "The ancestor, descendant, following, preceding and self axes partition a document",
1188 " <AAA>\n"
1189 " <BBB>\n"
1190 " <CCC/>\n"
1191 " <ZZZ/>\n"
1192 " </BBB>\n"
1193 " <XXX>\n"
1194 " <DDD>\n"
1195 " <EEE/>\n"
1196 " <FFF>\n"
1197 " <HHH/>\n"
1198 " <GGG>\n"
1199 " <JJJ>\n"
1200 " <QQQ/>\n"
1201 " </JJJ>\n"
1202 " <JJJ/>\n"
1203 " </GGG>\n"
1204 " <HHH/>\n"
1205 " </FFF>\n"
1206 " </DDD>\n"
1207 " </XXX>\n"
1208 " <CCC>\n"
1209 " <DDD/>\n"
1210 " </CCC>\n"
1211 " </AAA>\n"
1212 },
1214 {
1215 "//GGG/self::*",
1216 "The ancestor, descendant, following, preceding and self axes partition a document",
1217 " <AAA>\n"
1218 " <BBB>\n"
1219 " <CCC/>\n"
1220 " <ZZZ/>\n"
1221 " </BBB>\n"
1222 " <XXX>\n"
1223 " <DDD>\n"
1224 " <EEE/>\n"
1225 " <FFF>\n"
1226 " <HHH/>\n"
1227 " <GGG>\n"
1228 " <JJJ>\n"
1229 " <QQQ/>\n"
1230 " </JJJ>\n"
1231 " <JJJ/>\n"
1232 " </GGG>\n"
1233 " <HHH/>\n"
1234 " </FFF>\n"
1235 " </DDD>\n"
1236 " </XXX>\n"
1237 " <CCC>\n"
1238 " <DDD/>\n"
1239 " </CCC>\n"
1240 " </AAA>\n"
1241 },
1243 {
1244 "//GGG/ancestor::* | //GGG/descendant::* | //GGG/following::* | //GGG/preceding::* | //GGG/self::*",
1245 "The ancestor, descendant, following, preceding and self axes partition a document",
1246 " <AAA>\n"
1247 " <BBB>\n"
1248 " <CCC/>\n"
1249 " <ZZZ/>\n"
1250 " </BBB>\n"
1251 " <XXX>\n"
1252 " <DDD>\n"
1253 " <EEE/>\n"
1254 " <FFF>\n"
1255 " <HHH/>\n"
1256 " <GGG>\n"
1257 " <JJJ>\n"
1258 " <QQQ/>\n"
1259 " </JJJ>\n"
1260 " <JJJ/>\n"
1261 " </GGG>\n"
1262 " <HHH/>\n"
1263 " </FFF>\n"
1264 " </DDD>\n"
1265 " </XXX>\n"
1266 " <CCC>\n"
1267 " <DDD/>\n"
1268 " </CCC>\n"
1269 " </AAA>\n"
1270 },
1272 {
1273 "//BBB[position() mod 2 = 0 ]",
1274 "Select even BBB elements",
1275 " <AAA>\n"
1276 " <BBB/>\n"
1277 " <BBB/>\n"
1278 " <BBB/>\n"
1279 " <BBB/>\n"
1280 " <BBB/>\n"
1281 " <BBB/>\n"
1282 " <BBB/>\n"
1283 " <BBB/>\n"
1284 " <CCC/>\n"
1285 " <CCC/>\n"
1286 " <CCC/>\n"
1287 " </AAA>\n"
1288 },
1290 {
1291 "//BBB[ position() = floor(last() div 2 + 0.5) or position() = ceiling(last() div 2 + 0.5) ]",
1292 "Select middle BBB element(s)",
1293 " <AAA>\n"
1294 " <BBB/>\n"
1295 " <BBB/>\n"
1296 " <BBB/>\n"
1297 " <BBB/>\n"
1298 " <BBB/>\n"
1299 " <BBB/>\n"
1300 " <BBB/>\n"
1301 " <BBB/>\n"
1302 " <CCC/>\n"
1303 " <CCC/>\n"
1304 " <CCC/>\n"
1305 " </AAA>\n"
1306 },
1308 {
1309 "//CCC[ position() = floor(last() div 2 + 0.5) or position() = ceiling(last() div 2 + 0.5) ]",
1310 "Select middle CCC element(s)",
1311 " <AAA>\n"
1312 " <BBB/>\n"
1313 " <BBB/>\n"
1314 " <BBB/>\n"
1315 " <BBB/>\n"
1316 " <BBB/>\n"
1317 " <BBB/>\n"
1318 " <BBB/>\n"
1319 " <BBB/>\n"
1320 " <CCC/>\n"
1321 " <CCC/>\n"
1322 " <CCC/>\n"
1323 " </AAA>\n"
1324 },
1326 { //end data
1327 NULL,
1328 NULL,
1329 NULL,
1330 }
1332 };
1336 bool doStringTest(const char *str)
1337 {
1338 XPathParser xp;
1339 xp.setDebug(true);
1341 if (!xp.parse(str))
1342 return false;
1345 return true;
1346 }
1350 bool doStringTests()
1351 {
1352 for (XpathTest *xpt = xpathTests ; xpt->xpathStr ; xpt++)
1353 {
1354 if (!doStringTest(xpt->xpathStr))
1355 return false;
1356 }
1357 return true;
1358 }
1360 bool dumpDoc(DocumentPtr doc)
1361 {
1362 DOMImplementationLSImpl domImpl;
1363 LSSerializer &serializer = domImpl.createLSSerializer();
1364 LSOutput output = domImpl.createLSOutput();
1365 StdWriter writer;
1366 output.setCharacterStream(&writer);
1367 serializer.write(doc, output);
1369 return true;
1370 }
1373 bool doXmlTest(XpathTest *xpt)
1374 {
1375 printf("################################################################\n");
1377 //### READ
1378 DOMImplementationLSImpl domImpl;
1379 LSInput input = domImpl.createLSInput();
1380 LSParser &parser = domImpl.createLSParser(0, "");
1381 input.setStringData(xpt->xml);
1382 DocumentPtr doc = parser.parse(input);
1384 //### XPATH
1385 XPathParser xp;
1386 xp.setDebug(true);
1388 DOMString xpathStr = xpt->xpathStr;
1389 NodeList list = xp.evaluate(doc, xpathStr);
1390 for (unsigned int i=0 ; i<list.getLength() ; i++)
1391 {
1392 NodePtr n = list.item(i);
1393 printf("@@ node: %s\n", n->getNodeName().c_str());
1394 }
1396 //dumpDoc(doc);
1398 return true;
1399 }
1401 bool doXmlTests()
1402 {
1403 for (XpathTest *xpt = xpathTests ; xpt->xpathStr ; xpt++)
1404 {
1405 if (!doXmlTest(xpt))
1406 return false;
1407 }
1408 return true;
1409 }
1411 bool doTests()
1412 {
1413 /*
1414 if (!doStringTests())
1415 {
1416 printf("## Failed string tests\n");
1417 return false;
1418 }
1419 */
1420 if (!doXmlTests())
1421 {
1422 printf("## Failed xml tests\n");
1423 return false;
1424 }
1425 return true;
1426 }
1430 int main(int argc, char **argv)
1431 {
1432 doTests();
1433 return 0;
1434 }