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