1
/* Copyright 2005 Elliotte Rusty Harold
3
This library is free software; you can redistribute it and/or modify
4
it under the terms of version 2.1 of the GNU Lesser General Public
5
License as published by the Free Software Foundation.
7
This library is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU Lesser General Public License for more details.
12
You should have received a copy of the GNU Lesser General Public
13
License along with this library; if not, write to the
14
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
15
Boston, MA 02111-1307 USA
17
You can contact Elliotte Rusty Harold by sending e-mail to
18
elharo@metalab.unc.edu. Please include the word "XOM" in the
19
subject line. The XOM home page is located at http://www.xom.nu/
24
import java.io.ByteArrayOutputStream;
26
import java.io.IOException;
27
import java.io.PrintStream;
28
import java.net.MalformedURLException;
30
import nu.xom.Attribute;
31
import nu.xom.Builder;
32
import nu.xom.Comment;
33
import nu.xom.DocType;
34
import nu.xom.Document;
35
import nu.xom.Element;
36
import nu.xom.Elements;
37
import nu.xom.Namespace;
38
import nu.xom.NamespaceConflictException;
41
import nu.xom.ParsingException;
42
import nu.xom.ProcessingInstruction;
44
import nu.xom.XPathContext;
45
import nu.xom.XPathException;
46
import nu.xom.XPathTypeException;
50
* Unit tests for XPath functionality
53
* @author Elliotte Rusty Harold
57
public class XPathTest extends XOMTestCase {
59
public XPathTest(String name) {
64
// This class tests error conditions, which Xerces
65
// annoyingly logs to System.err. This hides System.err
66
// before each test and restores it after each test.
67
private PrintStream systemErr = System.err;
69
protected void setUp() {
70
System.setErr(new PrintStream(new ByteArrayOutputStream()));
74
protected void tearDown() {
75
System.setErr(systemErr);
78
public void testAllNodesQuery() {
80
Document doc = new Document(new Element("doc"));
81
Nodes subset = doc.query("//. | /");
82
assertEquals(2, subset.size());
95
public void testDescendantAxisOrder() {
97
Element a = new Element("a");
98
Document doc = new Document(a);
99
Element x1 = new Element("x");
100
x1.appendChild("a1");
101
Element x2 = new Element("x");
102
x2.appendChild("b2");
103
Element x3 = new Element("x");
104
x3.appendChild("c3");
105
Element x4 = new Element("x");
106
x4.appendChild("d4");
108
Element b = new Element("b");
113
Nodes result = doc.query("//x");
114
assertEquals(4, result.size());
115
assertTrue(result.get(0) instanceof Element);
116
assertTrue(result.get(1) instanceof Element);
117
assertTrue(result.get(2) instanceof Element);
118
assertTrue(result.get(3) instanceof Element);
119
assertEquals(x1, result.get(0));
120
assertEquals(x2, result.get(1));
121
assertEquals(x3, result.get(2));
122
assertEquals(x4, result.get(3));
127
public void testSimpleQuery() {
129
Element parent = new Element("Test");
130
Element child = new Element("child");
131
parent.appendChild(child);
133
Nodes result = parent.query("*");
134
assertEquals(1, result.size());
135
assertEquals(child, result.get(0));
140
public void testChildWildCard() {
142
Element a = new Element("a");
143
Element b = new Element("b");
144
Element c = new Element("c");
145
Element d = new Element("d");
151
Nodes result = a.query("/a/b/*/d");
152
assertEquals(1, result.size());
153
assertEquals(d, result.get(0));
158
public void testSimpleChild() {
160
Element a = new Element("a");
161
Nodes result = a.query("/a");
162
assertEquals(1, result.size());
167
public void testSimpleWildCard() {
169
Element a = new Element("a");
170
Nodes result = a.query("/*");
171
assertEquals(1, result.size());
176
public void testLongs() {
178
Document doc = new Document(new Element("root"));
180
Nodes result = doc.query("/*[5000000000=5000000000]");
181
assertEquals(1, result.size());
183
result = doc.query("/*[5000000000 < 5000000001]");
184
assertEquals(1, result.size());
185
result = doc.query("/*[5000000000 > 5000000001]");
186
assertEquals(0, result.size());
187
result = doc.query("/*[5000000001 >= 5000000001]");
188
assertEquals(1, result.size());
189
result = doc.query("/*[5000000001 > 5000000001]");
190
assertEquals(0, result.size());
195
public void testNamespaceNodeParent() {
197
Element root = new Element("root");
198
Document doc = new Document(root);
199
Element child = new Element("pre:child", "http://www.ietf.org");
200
root.appendChild(child);
202
Nodes result = doc.query("/root/*/namespace::*/parent::*");
203
assertEquals(1, result.size());
204
assertEquals(child, result.get(0));
209
public void testNamespaceNodeChild() {
211
Element root = new Element("root");
212
Document doc = new Document(root);
213
Element child = new Element("pre:child", "http://www.ietf.org");
214
root.appendChild(child);
216
Nodes result = doc.query("/root/*/namespace::*/child::*");
217
assertEquals(0, result.size());
222
// JAXEN-46: http://jira.codehaus.org/browse/JAXEN-46
223
public void testHashInAttributeValue() {
225
Element root = new Element("test");
226
Document doc = new Document(root);
227
Attribute test = new Attribute("test", "SUBSCRIBER");
228
Attribute test1 = new Attribute("test1", "SUBSCRIBER#");
229
root.addAttribute(test);
230
root.addAttribute(test1);
232
Nodes result = doc.query("test[@test='SUBSCRIBER']");
233
assertEquals(1, result.size());
234
assertEquals(root, result.get(0));
236
result = doc.query("test[@test1='SUBSCRIBER#']");
237
assertEquals(1, result.size());
238
assertEquals(root, result.get(0));
243
public void testUseRootNodeWhenQueryingDocumentLessElements() {
245
Element test = new Element("Test");
247
Nodes result = test.query("/*");
248
assertEquals(1, result.size());
249
assertEquals(test, result.get(0));
253
fail("Did not throw exception when querying rootless document for root");
255
catch (XPathException success) {
256
assertNotNull(success.getMessage());
262
public void testUseRootNodeWhenQueryingDocumentLessElements2() {
264
Element test = new Element("Test");
265
Nodes result = test.query("/None");
266
assertEquals(0, result.size());
271
public void testUseRootNodeWhenQueryingDocumentLessElements3() {
273
Element test = new Element("Test");
275
Nodes result = test.query("//*");
276
assertEquals(1, result.size());
281
public void testUseRootNodeWhenQueryingDocumentLessElements4() {
283
Element test = new Element("Test");
285
Nodes result = test.query("//* | /");
286
assertEquals(1, result.size());
291
public void testUnionOfNodesWithInts() {
293
Element parent = new Element("Test");
294
Element child = new Element("child");
295
parent.appendChild(child);
298
parent.query("* | count(/*)");
299
fail("Allowed query returning non-node-set");
301
catch (XPathException success) {
302
assertNotNull(success.getMessage());
308
public void testFranceschet1() throws ParsingException, IOException {
310
Builder builder = new Builder();
311
Document doc = builder.build(
312
"http://staff.science.uva.nl/~francesc/xpathmark/benchmark_canon.xml"
314
Element root = doc.getRootElement();
315
Elements inputs = root.getChildElements("document");
316
Element input = inputs.get(0).getFirstChildElement("site");
319
Nodes doc1Queries = root.query("child::query[starts-with(@id, 'Q')]");
321
for (int i = 0; i < doc1Queries.size(); i++) {
322
Element query = (Element) doc1Queries.get(i);
323
String xpath = query.getFirstChildElement("syntax").getValue();
324
String id = query.getAttributeValue("id");
325
// this query needs special comparison code due to
326
// adjacent text nodes
327
if ("Q21".equals(id)) continue;
328
// test suite bug relating to id() function
329
else if (xpath.indexOf("id(") >= 0) continue;
330
Nodes result = input.query(xpath);
331
Element answer = query.getFirstChildElement("answer");
332
Nodes expected = new Nodes();
333
for (int j = 0; j < answer.getChildCount(); j++) {
334
Node node = answer.getChild(j);
335
if (node instanceof Text) {
336
if (!("".equals(node.getValue().trim()))) {
337
expected.append(node);
341
expected.append(node);
344
assertEquals("Failed query " + id, expected.size(), result.size());
345
for (int j = 0; j < result.size(); j++) {
346
Node expectedNode = expected.get(j);
347
Node actualNode = result.get(j);
348
assertEquals(id + " " + expectedNode.toXML() + " " + actualNode.toXML(), expectedNode, actualNode);
355
public void testFranceschet2() throws ParsingException, IOException {
357
Builder builder = new Builder();
358
Document doc = builder.build(
359
"http://staff.science.uva.nl/~francesc/xpathmark/benchmark_canon.xml"
361
Element root = doc.getRootElement();
362
Elements inputs = root.getChildElements("document");
363
Element input = inputs.get(1);
364
Document html = new Document(new Element("fake"));
367
Node node = input.getChild(0);
368
if (node instanceof Element) break;
371
if (node instanceof Text) continue;
372
html.insertChild(node, p++);
375
Node newroot = input.getChild(0);
377
html.setRootElement((Element) newroot);
378
while (input.getChildCount() > 0) {
379
Node node = input.getChild(0);
381
if (node instanceof Text) continue;
382
html.appendChild(node);
385
Nodes doc2Queries = root.query("child::query[starts-with(@id, 'A')]");
387
XPathContext context = new XPathContext();
388
context.addNamespace("svg", "http://www.w3.org/2000/svg");
389
context.addNamespace("xlink", "http://www.w3.org/1999/xlink");
391
for (int i = 0; i < doc2Queries.size(); i++) {
392
Element query = (Element) doc2Queries.get(i);
393
String xpath = query.getFirstChildElement("syntax").getValue();
394
String id = query.getAttributeValue("id");
396
Nodes result = html.query(xpath, context);
397
Element answer = query.getFirstChildElement("answer");
398
Nodes expected = new Nodes();
399
for (int j = 0; j < answer.getChildCount(); j++) {
400
Node node = answer.getChild(j);
401
if (node instanceof Text) {
402
if (!("".equals(node.getValue().trim()))) {
403
expected.append(node);
407
expected.append(node);
410
assertEquals("Failed query " + id, expected.size(), result.size());
411
for (int j = 0; j < result.size(); j++) {
412
Node expectedNode = expected.get(j);
413
Node actualNode = result.get(j);
414
assertEquals(id + " " + expectedNode.toXML() + " "
415
+ actualNode.toXML(), expectedNode, actualNode);
422
public void testQueryThatReturnsNumber() {
424
Element parent = new Element("Test");
425
Element child = new Element("child");
426
parent.appendChild(child);
429
parent.query("count(*)");
430
fail("Allowed query to return number");
432
catch (XPathTypeException success) {
433
assertNotNull(success.getMessage());
434
assertEquals(new Double(1), success.getReturnValue());
435
assertEquals("count(*)", success.getXPath());
441
public void testStartsWith() {
443
Element parent = new Element("Test");
444
Element child = new Element("child");
445
child.addAttribute(new Attribute("foo", "bar"));
446
parent.appendChild(child);
447
Element child2 = new Element("child");
448
child2.addAttribute(new Attribute("foo", "big"));
449
parent.appendChild(child2);
451
Nodes result = parent.query(".//*[starts-with(@foo, 'ba')]");
452
assertEquals(1, result.size());
453
assertEquals(child, result.get(0));
458
// a jaxen extension function
459
public void testEndsWith() {
461
Element parent = new Element("Test");
462
Element child = new Element("child");
463
child.addAttribute(new Attribute("foo", "bar"));
464
parent.appendChild(child);
467
parent.query(".//*[ends-with(@foo, 'ar')]");
468
fail("Allowed Jaxen extension function");
470
catch (XPathException success) {
471
assertTrue(success.getMessage().indexOf("ends-with") >= 0);
477
public void testEmptyTextNodesDontCount() {
479
Element parent = new Element("Test");
480
Element child1 = new Element("child1");
481
parent.appendChild(child1);
482
parent.appendChild(new Text(""));
483
parent.appendChild(new Text(""));
484
Element child2 = new Element("child2");
485
parent.appendChild(child2);
487
Nodes result = parent.query("*");
488
assertEquals(2, result.size());
489
assertEquals(child1, result.get(0));
491
result = parent.query("*[2]");
492
assertEquals(1, result.size());
493
assertEquals(child2, result.get(0));
498
public void testEmptyTextNodesDontCount2() {
500
Element parent = new Element("Test");
501
parent.appendChild(new Text(""));
502
Element child1 = new Element("child1");
503
parent.appendChild(child1);
504
Element child2 = new Element("child2");
505
parent.appendChild(child2);
507
Nodes result = parent.query("node()");
508
assertEquals(2, result.size());
509
assertEquals(child1, result.get(0));
510
assertEquals(child2, result.get(1));
512
result = parent.query("node()[1]");
513
assertEquals(1, result.size());
514
assertEquals(child1, result.get(0));
519
public void testEmptyTextNodesAtEndOfParent() {
521
Element parent = new Element("Test");
522
Element child1 = new Element("child1");
523
parent.appendChild(child1);
524
Element child2 = new Element("child2");
525
parent.appendChild(child2);
526
parent.appendChild(new Text(""));
527
parent.appendChild(new Text(""));
528
parent.appendChild(new Text(""));
530
Nodes result = parent.query("node()");
531
assertEquals(2, result.size());
532
assertEquals(child1, result.get(0));
533
assertEquals(child2, result.get(1));
535
result = parent.query("node()[1]");
536
assertEquals(1, result.size());
537
assertEquals(child1, result.get(0));
542
public void testEmptyTextNodeNextToNonEmptyTextNode() {
544
Element parent = new Element("Test");
545
Text empty = new Text("");
546
parent.appendChild(empty);
547
Text nonempty = new Text("value");
548
parent.appendChild(nonempty);
549
Element child1 = new Element("child1");
550
parent.appendChild(child1);
551
Element child2 = new Element("child2");
552
parent.appendChild(child2);
554
Nodes result = parent.query("node()");
555
assertEquals(4, result.size());
556
assertEquals(empty, result.get(0));
557
assertEquals(nonempty, result.get(1));
559
result = parent.query("node()[1]");
560
assertEquals(2, result.size());
561
assertEquals(empty, result.get(0));
566
public void testBasicPredicate() {
568
Element parent = new Element("Test");
569
Element child1 = new Element("child");
570
child1.appendChild("1");
571
parent.appendChild(child1);
572
Element child2 = new Element("child");
573
child2.appendChild("2");
574
parent.appendChild(child2);
575
Element child3 = new Element("child");
576
child3.appendChild("3");
577
parent.appendChild(child3);
579
Nodes result = parent.query("*[.='2']");
580
assertEquals(1, result.size());
581
assertEquals(child2, result.get(0));
586
public void testXMLLang() {
588
Element parent = new Element("Test");
589
Element child1 = new Element("child");
590
child1.addAttribute(new Attribute("xml:lang",
591
"http://www.w3.org/XML/1998/namespace", "en"));
592
parent.appendChild(child1);
593
Element child2 = new Element("child");
594
child2.appendChild("2");
595
child2.addAttribute(new Attribute("xml:lang",
596
"http://www.w3.org/XML/1998/namespace", "fr"));
597
parent.appendChild(child2);
598
Element child3 = new Element("child");
599
child3.appendChild("3");
600
parent.appendChild(child3);
601
Element child4 = new Element("child");
602
child4.appendChild("4");
603
child4.addAttribute(new Attribute("xml:lang",
604
"http://www.w3.org/XML/1998/namespace", "en-US"));
605
parent.appendChild(child4);
607
Nodes result = parent.query("child::*[lang('en')]");
608
assertEquals(2, result.size());
609
assertEquals(child1, result.get(0));
610
assertEquals(child4, result.get(1));
615
public void testXMLPrefixIsAlwaysBound() {
617
Element parent = new Element("Test");
618
Element child1 = new Element("child");
619
child1.addAttribute(new Attribute("xml:lang",
620
"http://www.w3.org/XML/1998/namespace", "en"));
621
parent.appendChild(child1);
622
Element child2 = new Element("child");
623
child2.appendChild("2");
624
child2.addAttribute(new Attribute("xml:lang",
625
"http://www.w3.org/XML/1998/namespace", "fr"));
626
parent.appendChild(child2);
627
Element child3 = new Element("child");
628
child3.appendChild("3");
629
parent.appendChild(child3);
630
Element child4 = new Element("child");
631
child4.appendChild("4");
632
child4.addAttribute(new Attribute("xml:lang",
633
"http://www.w3.org/XML/1998/namespace", "en-US"));
634
parent.appendChild(child4);
636
Nodes result = parent.query("child::*/@xml:lang");
637
assertEquals(3, result.size());
642
public void testCantRebindXMLPrefix() {
644
XPathContext context = new XPathContext();
646
context.addNamespace("xml", "http://www.example.org");
647
fail("Rebound xml prefix");
649
catch (NamespaceConflictException success) {
650
assertNotNull(success.getMessage());
656
public void testParentAxis() {
658
Element parent = new Element("Test");
659
Element child = new Element("child");
660
parent.appendChild(child);
662
Nodes result = child.query("parent::*");
663
assertEquals(1, result.size());
664
assertEquals(parent, result.get(0));
669
public void testAncestorAxis() {
671
Element grandparent = new Element("Test");
672
new Document(grandparent);
673
Element parent = new Element("Test");
674
Element child = new Element("child");
675
parent.appendChild(child);
676
grandparent.appendChild(parent);
678
Nodes result = child.query("ancestor::*");
679
assertEquals(2, result.size());
680
assertEquals(grandparent, result.get(0));
681
assertEquals(parent, result.get(1));
686
public void testParentAxisWithDocument() {
688
Element root = new Element("Test");
691
Nodes result = root.query("parent::*");
692
assertEquals(0, result.size());
697
public void testParentAxisWithNodeMatchingDocument() {
699
Element root = new Element("Test");
700
Document doc = new Document(root);
702
Nodes result = root.query("parent::node()");
703
assertEquals(1, result.size());
704
assertEquals(doc, result.get(0));
709
public void testSubstringFunction() {
711
Element root = new Element("Test");
714
Nodes result = root.query("/*[substring('12345', 0, 3)='12']");
715
assertEquals(1, result.size());
716
assertEquals(root, result.get(0));
721
public void testPrecedingAxisWithElementName() {
723
Element root = new Element("Test");
724
Document doc = new Document(root);
726
Nodes result = doc.query("/descendant::*/preceding::x");
727
assertEquals(0, result.size());
734
public void testDocTypeIsNotAnXPathNode() {
736
Element root = new Element("root");
737
Document doc = new Document(root);
738
DocType doctype = new DocType("root");
739
doc.setDocType(doctype);
741
Nodes result = doc.query("child::node()[1]");
742
assertEquals(1, result.size());
743
assertEquals(root, result.get(0));
748
public void testGetNodeBeforeDocType() {
750
Element root = new Element("root");
751
Document doc = new Document(root);
752
DocType doctype = new DocType("root");
753
doc.setDocType(doctype);
754
Comment c = new Comment("test");
755
doc.insertChild(c, 0);
757
Nodes result = doc.query("child::node()[1]");
758
assertEquals(1, result.size());
759
assertEquals(c, result.get(0));
764
public void testCantUseDocTypeAsXPathContextNode() {
766
Element root = new Element("root");
767
Document doc = new Document(root);
768
DocType doctype = new DocType("root");
769
doc.setDocType(doctype);
773
fail("Allowed DocType as context node");
775
catch (XPathException success) {
776
assertNotNull(success.getMessage());
782
public void testDescendantAxis() {
784
Element grandparent = new Element("Test");
785
Document doc = new Document(grandparent);
786
Element parent = new Element("Test");
787
Element child = new Element("child");
788
parent.appendChild(child);
789
grandparent.appendChild(parent);
791
Nodes result = doc.query("descendant::*");
792
assertEquals(3, result.size());
793
assertEquals(grandparent, result.get(0));
794
assertEquals(parent, result.get(1));
795
assertEquals(child, result.get(2));
800
public void testGetElementQName() {
802
Element grandparent = new Element("Test");
803
Document doc = new Document(grandparent);
804
Element parent = new Element("Test");
805
Element child1 = new Element("pre:child", "http://www.example.org/");
806
Element child2 = new Element("pre:child", "http://www.example.com/");
807
parent.appendChild(child1);
808
parent.appendChild(child2);
809
grandparent.appendChild(parent);
811
Nodes result = doc.query("descendant::*[name(.)='pre:child']");
812
assertEquals(2, result.size());
813
assertEquals(child1, result.get(0));
814
assertEquals(child2, result.get(1));
819
// This does not actually hit the method I was aiming at.
820
// Apparently, Jaxen never actually invokes
821
// getElementStringValue()
822
public void testGetElementStringValue() {
824
Element grandparent = new Element("Test");
825
Document doc = new Document(grandparent);
826
Element parent = new Element("Test");
827
Element child1 = new Element("child");
828
child1.appendChild("foo");
829
Element child2 = new Element("child");
830
child2.appendChild("bar");
831
parent.appendChild(child1);
832
parent.appendChild(child2);
833
grandparent.appendChild(parent);
835
Nodes result = doc.query("descendant::*[.='foo']");
836
assertEquals(1, result.size());
837
assertEquals(child1, result.get(0));
842
public void testGetNonExistentNode() {
844
Element grandparent = new Element("Test");
845
Document doc = new Document(grandparent);
846
Element parent = new Element("Test");
847
Element child1 = new Element("child");
848
child1.appendChild("foo");
849
Element child2 = new Element("child");
850
child2.appendChild("bar");
851
parent.appendChild(child1);
852
parent.appendChild(child2);
853
grandparent.appendChild(parent);
855
Nodes result = doc.query("/Test/Test/*[12]");
856
assertEquals(0, result.size());
861
public void testGetAttributeQName() {
863
Element grandparent = new Element("Test");
864
Document doc = new Document(grandparent);
865
Element parent = new Element("Test");
866
Attribute a1 = new Attribute("pre:attribute", "http://www.example.org/", "test");
867
Attribute a2 = new Attribute("pre:attribute", "http://www.example.com/", "test");
868
parent.addAttribute(a2);
869
grandparent.addAttribute(a1);
870
grandparent.appendChild(parent);
872
Nodes result = doc.query("descendant::*/attribute::*[name(.)='pre:attribute']");
873
assertEquals(2, result.size());
874
assertTrue(result.contains(a1));
875
assertTrue(result.contains(a2));
880
public void testGetNamespaceStringValue() {
882
Element test = new Element("Test", "http://www.example.com/");
884
Nodes result = test.query("self::*[contains(namespace::*, 'http://')]");
885
assertEquals(1, result.size());
886
assertEquals(test, result.get(0));
891
private File inputDir = new File("data");
894
public void testGetDocument() throws MalformedURLException {
896
Element element = new Element("test");
897
File f = new File(inputDir, "prettyxml.xml");
898
String url = f.toURL().toExternalForm();
900
element.query("document('" + url + "')/*");
901
fail("allowed document() function");
903
catch(XPathException success) {
904
assertTrue(success.getMessage().indexOf("document") >= 0);
910
public void testGetMultipleNodesViaDocumentFunction()
911
throws MalformedURLException {
913
Element element = new Element("test");
914
File f = new File(inputDir, "prettyxml.xml");
915
String url = f.toURL().toExternalForm();
917
element.query("document('" + url + "')//*");
918
fail("allowed document() function");
920
catch(XPathException success) {
921
assertTrue(success.getMessage().indexOf("document") >= 0);
927
public void testDoubleDocument() throws MalformedURLException {
929
Element element = new Element("test");
930
File f1 = new File(inputDir, "prettyxml.xml");
931
String url1 = f1.toURL().toExternalForm();
932
File f2 = new File(inputDir, "test.xml");
933
String url2 = f2.toURL().toExternalForm();
935
element.query("document('" + url1 + "')/* | "
936
+ "document('" + url2 + "')/*");
937
fail("allowed document() function");
939
catch(XPathException success) {
940
assertTrue(success.getMessage().indexOf("document") >= 0);
946
public void testGetNonExistentDocument() {
948
Element element = new Element("test");
950
element.query("document('http://www.ibiblio.org/aksdjhk/')/*");
951
fail("That file doesn't exist!");
953
catch (XPathException success) {
954
assertNotNull(success.getMessage());
960
public void testMalformedDocument() {
962
Element element = new Element("test");
964
element.query("document('http://www.cafeaulait.org/formatter/Formatter.java')/*");
965
fail("Queried malformed document!");
967
catch (XPathException success) {
968
assertNotNull(success.getMessage());
974
public void testGetDocumentNode() {
976
Element element = new Element("test");
977
Document doc = new Document(element);
978
Nodes result = element.query("/");
979
assertEquals(1, result.size());
980
assertEquals(doc, result.get(0));
985
public void testCommentNodeTest() {
987
Element grandparent = new Element("Test");
988
Document doc = new Document(grandparent);
989
Element parent = new Element("Test");
990
Element child = new Element("child");
991
parent.appendChild(child);
992
grandparent.appendChild(parent);
994
Comment c1 = new Comment("c1");
995
Comment c2 = new Comment("c2");
996
Comment c3 = new Comment("c3");
997
Comment c4 = new Comment("c4");
999
doc.insertChild(c1, 0);
1000
grandparent.insertChild(c2, 0);
1001
parent.insertChild(c3, 0);
1002
child.insertChild(c4, 0);
1004
Nodes result = doc.query("descendant::comment()");
1005
assertEquals(4, result.size());
1006
assertEquals(c1, result.get(0));
1007
assertEquals(c2, result.get(1));
1008
assertEquals(c3, result.get(2));
1009
assertEquals(c4, result.get(3));
1014
public void testCommentStringValue() {
1016
Element grandparent = new Element("Test");
1017
Document doc = new Document(grandparent);
1018
Element parent = new Element("Test");
1019
Element child = new Element("child");
1020
parent.appendChild(child);
1021
grandparent.appendChild(parent);
1023
Comment c1 = new Comment("c1");
1024
Comment c2 = new Comment("c2");
1025
Comment c3 = new Comment("c3");
1026
Comment c4 = new Comment("c4");
1028
doc.insertChild(c1, 0);
1029
grandparent.insertChild(c2, 0);
1030
parent.insertChild(c3, 0);
1031
child.insertChild(c4, 0);
1033
Nodes result = doc.query("descendant::comment()[.='c3']");
1034
assertEquals(1, result.size());
1035
assertEquals(c3, result.get(0));
1040
public void testGetProcessingInstructionData() {
1042
Element grandparent = new Element("Test");
1043
Document doc = new Document(grandparent);
1044
Element parent = new Element("Test");
1045
Element child = new Element("child");
1046
parent.appendChild(child);
1047
grandparent.appendChild(parent);
1049
ProcessingInstruction p1 = new ProcessingInstruction("c1", "1");
1050
ProcessingInstruction p2 = new ProcessingInstruction("c1", "2");
1051
ProcessingInstruction p3 = new ProcessingInstruction("c1", "3");
1052
ProcessingInstruction p4 = new ProcessingInstruction("c1", "4");
1054
doc.insertChild(p1, 0);
1055
grandparent.insertChild(p2, 0);
1056
parent.insertChild(p3, 0);
1057
child.insertChild(p4, 0);
1059
Nodes result = doc.query("descendant::processing-instruction()[.='3']");
1060
assertEquals(1, result.size());
1061
assertEquals(p3, result.get(0));
1066
public void testProcessingInstructionNodeTest() {
1068
Element grandparent = new Element("Test");
1069
Document doc = new Document(grandparent);
1070
Element parent = new Element("Test");
1071
Element child = new Element("child");
1072
parent.appendChild(child);
1073
grandparent.appendChild(parent);
1075
Comment c1 = new Comment("c1");
1076
Comment c2 = new Comment("c2");
1077
Comment c3 = new Comment("c3");
1078
Comment c4 = new Comment("c4");
1080
doc.insertChild(c1, 0);
1081
grandparent.insertChild(c2, 0);
1082
parent.insertChild(c3, 0);
1083
child.insertChild(c4, 0);
1084
ProcessingInstruction pi = new ProcessingInstruction("appendix", "text");
1085
doc.appendChild(pi);
1086
ProcessingInstruction pi2 = new ProcessingInstruction("test", "text");
1087
parent.appendChild(pi2);
1089
Nodes result = doc.query("descendant::processing-instruction('test')");
1090
assertEquals(1, result.size());
1091
assertEquals(pi2, result.get(0));
1096
public void testDescendantOrSelfAxis() {
1098
Element grandparent = new Element("Test");
1099
Element parent = new Element("Test");
1100
Element child = new Element("child");
1101
parent.appendChild(child);
1102
grandparent.appendChild(parent);
1104
Nodes result = grandparent.query("descendant-or-self::*");
1105
assertEquals(3, result.size());
1106
assertEquals(grandparent, result.get(0));
1107
assertEquals(parent, result.get(1));
1108
assertEquals(child, result.get(2));
1113
public void testAncestorOrSelfAxis() {
1115
Element grandparent = new Element("Test");
1116
new Document(grandparent);
1117
Element parent = new Element("Test");
1118
Element child = new Element("child");
1119
parent.appendChild(child);
1120
grandparent.appendChild(parent);
1122
Nodes result = child.query("ancestor-or-self::*");
1123
assertEquals(3, result.size());
1124
assertEquals(child, result.get(2));
1125
assertEquals(parent, result.get(1));
1126
assertEquals(grandparent, result.get(0));
1131
public void testSelfAxis() {
1133
Element parent = new Element("Test");
1134
Element child = new Element("child");
1135
parent.appendChild(child);
1137
Nodes result = child.query("self::*");
1138
assertEquals(1, result.size());
1139
assertEquals(child, result.get(0));
1140
result = parent.query("self::*");
1141
assertEquals(1, result.size());
1142
assertEquals(parent, result.get(0));
1147
public void testSelfAxisWithUnparentedText() {
1149
Text text = new Text("test");
1150
Nodes result = text.query("self::text()");
1151
assertEquals(1, result.size());
1152
assertEquals(text, result.get(0));
1156
public void testSelfAxisWithAttribute() {
1158
Element e = new Element("child");
1159
e.addAttribute(new Attribute("test", "value"));
1160
Nodes result = e.query("@*[self::test]");
1161
assertEquals(0, result.size());
1166
public void testSelfAxisWithTextChild() {
1168
Element parent = new Element("parent");
1169
Node child = new Text("child");
1170
parent.appendChild(child);
1171
Nodes result = child.query("self::text()");
1172
assertEquals(1, result.size());
1173
assertEquals(child, result.get(0));
1178
public void testSelfAxisWithTextChildren() {
1180
Element parent = new Element("parent");
1181
Node child1 = new Text("1");
1182
Node child2 = new Text("2");
1183
Node child3 = new Text("3");
1184
Node child4 = new Text("4");
1185
parent.appendChild(child1);
1186
parent.appendChild(child2);
1187
parent.appendChild(child3);
1188
parent.appendChild(child4);
1189
Nodes result = child1.query("self::text()");
1190
assertEquals(4, result.size());
1191
assertEquals(child1, result.get(0));
1192
assertEquals(child2, result.get(1));
1193
assertEquals(child3, result.get(2));
1194
assertEquals(child4, result.get(3));
1199
public void testSelfAxisWithTextChildren2() {
1201
Element parent = new Element("parent");
1202
Node child1 = new Text("1");
1203
Node child2 = new Text("2");
1204
Node child3 = new Text("3");
1205
Node child4 = new Text("4");
1206
parent.appendChild(child1);
1207
parent.appendChild(child2);
1208
parent.appendChild(child3);
1209
parent.appendChild(child4);
1210
Nodes result = child3.query("self::text()");
1211
assertEquals(4, result.size());
1212
assertEquals(child1, result.get(0));
1213
assertEquals(child2, result.get(1));
1214
assertEquals(child3, result.get(2));
1215
assertEquals(child4, result.get(3));
1220
public void testSelfAxisWithTextChildAndNoParent() {
1222
Node child = new Text("child");
1223
Nodes result = child.query("self::text()");
1224
assertEquals(1, result.size());
1225
assertEquals(child, result.get(0));
1230
public void testAttributeAxis() {
1232
Element parent = new Element("Test");
1233
Element child = new Element("child");
1234
parent.appendChild(child);
1235
parent.addAttribute(new Attribute("name", "value"));
1236
parent.addAttribute(new Attribute("name2", "value"));
1238
Nodes result = child.query("attribute::*");
1239
assertEquals(0, result.size());
1240
result = parent.query("attribute::*");
1241
assertEquals(2, result.size());
1242
result = parent.query("attribute::name");
1243
assertEquals(1, result.size());
1248
public void testAttributeAxisOnNonElement() {
1250
Text text = new Text("Test");
1251
Nodes result = text.query("attribute::*");
1252
assertEquals(0, result.size());
1257
public void testEmptyParentAxis() {
1259
Element parent = new Element("Test");
1260
Element child = new Element("child");
1261
parent.appendChild(child);
1263
Nodes result = parent.query("parent::*");
1264
assertEquals(0, result.size());
1269
public void testPrecedingSiblingAxis() {
1271
Element parent = new Element("Test");
1272
Element child1 = new Element("child1");
1273
Element child2 = new Element("child2");
1274
Element child3 = new Element("child3");
1275
parent.appendChild(child1);
1276
parent.appendChild(child2);
1277
parent.appendChild(child3);
1279
Nodes result = child1.query("preceding-sibling::*");
1280
assertEquals(0, result.size());
1281
result = child2.query("preceding-sibling::*");
1282
assertEquals(1, result.size());
1283
assertEquals(child1, result.get(0));
1284
result = child3.query("preceding-sibling::*");
1285
assertEquals(2, result.size());
1290
public void testAttributeHasNoSiblings() {
1292
Element parent = new Element("Test");
1293
Element child1 = new Element("child1");
1294
Element child2 = new Element("child2");
1295
Element child3 = new Element("child3");
1296
parent.appendChild(child1);
1297
parent.appendChild(child2);
1298
parent.appendChild(child3);
1299
Attribute a1 = new Attribute("a1", "value");
1300
Attribute a2 = new Attribute("a2", "value");
1301
Attribute a3 = new Attribute("a3", "value");
1302
child2.addAttribute(a1);
1303
child2.addAttribute(a2);
1304
child2.addAttribute(a3);
1306
Nodes result = a2.query("preceding-sibling::node()");
1307
assertEquals(0, result.size());
1308
result = a2.query("following-sibling::node()");
1309
assertEquals(0, result.size());
1314
public void testIDFunction() {
1316
Element parent = new Element("Test");
1317
Element child1 = new Element("child1");
1318
Element child2 = new Element("child2");
1319
Element child3 = new Element("child3");
1320
Attribute id = new Attribute("a", "anchor");
1321
id.setType(Attribute.Type.ID);
1322
child2.addAttribute(id);
1324
parent.appendChild(child1);
1325
parent.appendChild(child2);
1326
parent.appendChild(child3);
1328
Nodes result = parent.query("id('anchor')");
1329
assertEquals(1, result.size());
1330
assertEquals(child2, result.get(0));
1335
public void testIDQueryOnDocumentNode() {
1337
Element parent = new Element("Test");
1338
Element child1 = new Element("child1");
1339
Element child2 = new Element("child2");
1340
Element child3 = new Element("child3");
1341
Attribute id = new Attribute("a", "anchor");
1342
id.setType(Attribute.Type.ID);
1343
child2.addAttribute(id);
1345
parent.appendChild(child1);
1346
parent.appendChild(child2);
1347
parent.appendChild(child3);
1348
Document doc = new Document(parent);
1350
Nodes result = doc.query("id('anchor')");
1351
assertEquals(1, result.size());
1352
assertEquals(child2, result.get(0));
1357
public void testIDFunctionWithoutType() {
1359
Element parent = new Element("Test");
1360
Element child1 = new Element("child1");
1361
Element child2 = new Element("child2");
1362
Element child3 = new Element("child3");
1363
Attribute id = new Attribute("id", "anchor");
1364
child2.addAttribute(id);
1366
parent.appendChild(child1);
1367
parent.appendChild(child2);
1368
parent.appendChild(child3);
1370
Nodes result = parent.query("id('anchor')");
1371
assertEquals(0, result.size());
1376
public void testIDFunctionFromTextNode() {
1378
Element parent = new Element("Test");
1379
Element child1 = new Element("child1");
1380
Element child2 = new Element("child2");
1381
Element child3 = new Element("child3");
1382
Text text = new Text("test");
1383
child3.appendChild(text);
1384
Attribute id = new Attribute("a", "anchor");
1385
id.setType(Attribute.Type.ID);
1386
child2.addAttribute(id);
1388
parent.appendChild(child1);
1389
parent.appendChild(child2);
1390
parent.appendChild(child3);
1392
Nodes result = text.query("id('anchor')");
1393
assertEquals(1, result.size());
1394
assertEquals(child2, result.get(0));
1399
public void testIDFunctionFromUnparentedTextNode() {
1401
Text text = new Text("test");
1402
Nodes result = text.query("id('anchor')");
1403
assertEquals(0, result.size());
1408
public void testIDFunctionFromDisconnectedTextNode() {
1410
Text text = new Text("test");
1411
Nodes result = text.query("id('anchor')");
1412
assertEquals(0, result.size());
1417
public void testFollowingSiblingAxis() {
1419
Element parent = new Element("Test");
1420
Element child1 = new Element("child1");
1421
Element child2 = new Element("child2");
1422
Element child3 = new Element("child3");
1423
parent.appendChild(child1);
1424
parent.appendChild(child2);
1425
parent.appendChild(child3);
1427
Nodes result = child3.query("following-sibling::*");
1428
assertEquals(0, result.size());
1429
result = child2.query("following-sibling::*");
1430
assertEquals(1, result.size());
1431
assertEquals(child3, result.get(0));
1432
result = child1.query("following-sibling::*");
1433
assertEquals(2, result.size());
1438
public void testNamespaceQuery() {
1440
Element parent = new Element("Test", "http://www.example.org");
1441
Element child = new Element("child", "http://www.example.org");
1442
parent.appendChild(child);
1444
XPathContext context = new XPathContext("pre", "http://www.example.org");
1445
Nodes result = parent.query("child::pre:child", context);
1446
assertEquals(1, result.size());
1447
assertEquals(child, result.get(0));
1452
public void testNamespaceAxis() {
1454
Element parent = new Element("Test", "http://www.example.org");
1456
Nodes result = parent.query("namespace::*");
1457
assertEquals(2, result.size());
1458
Namespace n1 = (Namespace) result.get(0);
1459
Namespace n2 = (Namespace) result.get(1);
1460
assertTrue(n1.getPrefix().equals("") || n2.getPrefix().equals(""));
1461
assertTrue(n1.getPrefix().equals("xml") || n2.getPrefix().equals("xml"));
1462
assertTrue(n1.getValue().equals("http://www.example.org")
1463
|| n2.getValue().equals("http://www.example.org"));
1464
assertTrue(n1.getValue().equals(Namespace.XML_NAMESPACE)
1465
|| n2.getValue().equals(Namespace.XML_NAMESPACE));
1470
public void testNamespaceAxisFromNonElement() {
1472
Text text = new Text("test");
1474
Nodes result = text.query("namespace::*");
1475
assertEquals(0, result.size());
1480
public void testPredicateWithNamespaceAxis() {
1482
Element parent = new Element("Test");
1483
Element child = new Element("child", "http://www.example.com");
1484
Element grandchild = new Element("child", "http://www.example.com");
1485
grandchild.addNamespaceDeclaration("pre", "http://www.w3.org/");
1486
parent.appendChild(child);
1487
child.appendChild(grandchild);
1489
// Every node has at least a mapping for xml prefix.
1490
Nodes result = parent.query("self::*[count(namespace::*)=0]");
1491
assertEquals(0, result.size());
1493
result = parent.query("self::*[count(namespace::*)=1]");
1494
assertEquals(1, result.size());
1495
assertEquals(parent, result.get(0));
1497
result = child.query("self::*[count(namespace::*)=2]");
1498
assertEquals(1, result.size());
1499
assertEquals(child, result.get(0));
1501
result = grandchild.query("self::*[count(namespace::*)=3]");
1502
assertEquals(1, result.size());
1503
assertEquals(grandchild, result.get(0));
1508
public void testPredicateWithNamespaceAxis2() {
1510
Element parent = new Element("Test");
1511
Element child = new Element("child", "http://www.example.com");
1512
Element grandchild = new Element("child", "http://www.example.com");
1513
grandchild.addNamespaceDeclaration("pre", "http://www.w3.org/");
1514
parent.appendChild(child);
1515
child.appendChild(grandchild);
1517
// Every node has at least a mapping for xml prefix.
1518
Nodes result = parent.query("*[count(namespace::*)=0]");
1519
assertEquals(0, result.size());
1521
result = parent.query(".//self::*[count(namespace::*)=1]");
1522
assertEquals(1, result.size());
1523
assertEquals(parent, result.get(0));
1525
result = parent.query(".//*[count(namespace::*)=2]");
1526
assertEquals(1, result.size());
1527
assertEquals(child, result.get(0));
1529
result = parent.query(".//*[count(namespace::*)=3]");
1530
assertEquals(1, result.size());
1531
assertEquals(grandchild, result.get(0));
1536
public void testNamespaceQueryWithNullPrefix() {
1539
XPathContext context = new XPathContext("pre", "http://www.example.org");
1540
context.addNamespace(null, "http://www.w3.org");
1541
fail("Allowed null prefix");
1543
catch (NullPointerException success) {
1544
assertNotNull(success.getMessage());
1550
public void testNamespaceQueryWithNullPrefix2() {
1553
new XPathContext(null, "http://www.example.org");
1554
fail("Allowed null prefix");
1556
catch (NullPointerException success) {
1557
assertNotNull(success.getMessage());
1563
public void testNamespaceQueryWithEmptyPrefix() {
1566
XPathContext context = new XPathContext("pre", "http://www.example.org");
1567
context.addNamespace("", "http://www.w3.org");
1569
catch (NamespaceConflictException success) {
1570
assertTrue(success.getMessage().length() > 1);
1576
public void testNamespaceQueryWithEmptyPrefix2() {
1579
new XPathContext("", "http://www.example.org");
1581
catch (NamespaceConflictException success) {
1582
assertTrue(success.getMessage().length() > 1);
1588
public void testNamespaceQueryWithNullURI() {
1590
Element parent = new Element("Test", "http://www.example.org");
1591
Element child = new Element("child", "http://www.example.org");
1592
parent.appendChild(child);
1594
XPathContext context = new XPathContext("pre", null);
1596
parent.query("child::pre:child", context);
1597
fail("Allowed null URI");
1599
catch (XPathException success) {
1600
assertNotNull(success.getCause());
1601
assertNotNull(success.getMessage());
1607
public void testNamespaceQueryWithEmptyURI() {
1609
Element parent = new Element("Test", "http://www.example.org");
1610
Element child = new Element("child", "http://www.example.org");
1611
parent.appendChild(child);
1613
XPathContext context = new XPathContext("pre", "");
1615
parent.query("child::pre:child", context);
1616
fail("Allowed empty string as namespace URI");
1618
catch (XPathException success) {
1619
assertNotNull(success.getCause());
1620
assertNotNull(success.getMessage());
1626
public void testNamespaceQueryWithReboundPrefix() {
1628
Element parent = new Element("Test", "http://www.example.org");
1629
Element child = new Element("child", "http://www.example.org");
1630
parent.appendChild(child);
1632
XPathContext context = new XPathContext("pre", "http://www.example.com");
1633
Nodes result = parent.query("child::pre:child", context);
1634
assertEquals(0, result.size());
1636
context.addNamespace("pre", "http://www.example.org");
1637
result = parent.query("child::pre:child", context);
1638
assertEquals(1, result.size());
1639
assertEquals(child, result.get(0));
1644
public void testNamespaceQueryWithUnboundPrefix() {
1646
Element parent = new Element("Test", "http://www.example.org");
1647
Element child = new Element("child", "http://www.example.org");
1648
parent.appendChild(child);
1650
XPathContext context = new XPathContext("not", "http://www.example.com");
1652
parent.query("child::pre:child", context);
1653
fail("Queried with unbound prefix");
1655
catch (XPathException success) {
1656
assertNotNull(success.getMessage());
1657
assertNotNull(success.getCause());
1661
parent.query("child::pre:child");
1662
fail("Queried with unbound prefix");
1664
catch (XPathException success) {
1665
assertNotNull(success.getMessage());
1666
assertNotNull(success.getCause());
1672
public void testElementBasedNamespaceContext() {
1674
Element parent = new Element("Test", "http://www.example.org");
1675
Element child = new Element("child", "http://www.example.org");
1676
parent.appendChild(child);
1678
Element test = new Element("pre:test", "http://www.example.org");
1679
XPathContext context = XPathContext.makeNamespaceContext(test);
1680
Nodes result = parent.query("child::pre:child", context);
1681
assertEquals(1, result.size());
1682
assertEquals(child, result.get(0));
1687
public void testAttributeBasedNamespaceContext() {
1689
Element parent = new Element("Test", "http://www.example.org");
1690
Element child = new Element("child", "http://www.example.org");
1691
parent.appendChild(child);
1693
Element test = new Element("test");
1694
test.addAttribute(new Attribute("pre:test", "http://www.example.org", "value"));
1695
XPathContext context = XPathContext.makeNamespaceContext(test);
1696
Nodes result = parent.query("child::pre:child", context);
1697
assertEquals(1, result.size());
1698
assertEquals(child, result.get(0));
1703
public void testAdditionalNamespaceBasedNamespaceContext() {
1705
Element parent = new Element("Test", "http://www.example.org");
1706
Element child = new Element("child", "http://www.example.org");
1707
parent.appendChild(child);
1709
Element test = new Element("test");
1710
test.addNamespaceDeclaration("pre", "http://www.example.org");
1711
XPathContext context = XPathContext.makeNamespaceContext(test);
1712
Nodes result = parent.query("child::pre:child", context);
1713
assertEquals(1, result.size());
1714
assertEquals(child, result.get(0));
1719
public void testAncestorElementBasedNamespaceContext() {
1721
Element parent = new Element("Test", "http://www.example.org");
1722
Element child = new Element("child", "http://www.example.org");
1723
parent.appendChild(child);
1725
Element test = new Element("pre:test", "http://www.example.org");
1726
Element testChild = new Element("testchild");
1727
test.appendChild(testChild);
1728
XPathContext context = XPathContext.makeNamespaceContext(testChild);
1729
Nodes result = parent.query("child::pre:child", context);
1730
assertEquals(1, result.size());
1731
assertEquals(child, result.get(0));
1736
public void testAncestorAttributeBasedNamespaceContext() {
1738
Element parent = new Element("Test", "http://www.example.org");
1739
Element child = new Element("child", "http://www.example.org");
1740
parent.appendChild(child);
1742
Element test = new Element("test");
1743
test.addAttribute(new Attribute("pre:test", "http://www.example.org", "value"));
1744
Element testChild = new Element("testchild");
1745
test.appendChild(testChild);
1746
XPathContext context = XPathContext.makeNamespaceContext(testChild);
1747
Nodes result = parent.query("child::pre:child", context);
1748
assertEquals(1, result.size());
1749
assertEquals(child, result.get(0));
1754
public void testAncestorAdditionalNamespaceBasedNamespaceContext() {
1756
Element parent = new Element("Test", "http://www.example.org");
1757
Element child = new Element("child", "http://www.example.org");
1758
parent.appendChild(child);
1760
Element test = new Element("test");
1761
test.addNamespaceDeclaration("pre", "http://www.example.org");
1762
Element testChild = new Element("testchild");
1763
test.appendChild(testChild);
1764
XPathContext context = XPathContext.makeNamespaceContext(testChild);
1765
Nodes result = parent.query("child::pre:child", context);
1766
assertEquals(1, result.size());
1767
assertEquals(child, result.get(0));
1772
public void testPrefixedNamespaceQuery() {
1774
Element parent = new Element("a:Test", "http://www.example.org");
1775
Element child = new Element("b:child", "http://www.example.org");
1776
Attribute att = new Attribute("c:dog", "http://www.cafeconleche.org/", "test");
1777
parent.appendChild(child);
1778
child.addAttribute(att);
1780
XPathContext context = new XPathContext("pre", "http://www.example.org");
1781
context.addNamespace("c", "http://www.cafeconleche.org/");
1782
Nodes result = parent.query("child::pre:child", context);
1783
assertEquals(1, result.size());
1784
assertEquals(child, result.get(0));
1786
result = child.query("@c:*", context);
1787
assertEquals(1, result.size());
1788
assertEquals(att, result.get(0));
1793
public void testBradley() {
1795
Element element = new Element("root");
1796
Text t1 = new Text("makes ");
1797
Text t2 = new Text("a");
1798
Text t3 = new Text(" good");
1799
Text t4 = new Text(" point.");
1800
Element child = new Element("someElement");
1801
Text t5 = new Text(" Yes");
1802
Text t6 = new Text(" he");
1803
Text t7 = new Text(" does!");
1804
element.appendChild(t1);
1805
element.appendChild(t2);
1806
element.appendChild(t3);
1807
element.appendChild(t4);
1808
element.appendChild(child);
1809
element.appendChild(t5);
1810
element.appendChild(t6);
1811
element.appendChild(t7);
1813
Nodes result = element.query("./text()[contains(., 'o')]");
1814
assertEquals(7, result.size());
1815
assertEquals(t1, result.get(0));
1816
assertEquals(t2, result.get(1));
1817
assertEquals(t3, result.get(2));
1818
assertEquals(t4, result.get(3));
1819
assertEquals(t5, result.get(4));
1820
assertEquals(t6, result.get(5));
1821
assertEquals(t7, result.get(6));
1827
public void testNamespaceQueryWithAdjacentTextNodes() {
1829
Element parent = new Element("Test", "http://www.example.org");
1830
Element child = new Element("child", "http://www.example.org");
1831
parent.appendChild(child);
1832
child.appendChild("1");
1833
child.appendChild("2");
1835
XPathContext context = new XPathContext("pre", "http://www.example.org");
1836
Nodes result = parent.query("descendant::text()", context);
1837
assertEquals(2, result.size());
1838
assertEquals("1", result.get(0).getValue());
1839
assertEquals("2", result.get(1).getValue());
1844
public void testNamespaceQueryWithoutPrefixMapping() {
1846
Element parent = new Element("Test", "http://www.example.org");
1847
Element child = new Element("child", "http://www.example.org");
1848
parent.appendChild(child);
1850
Nodes result = parent.query("child");
1851
assertEquals(0, result.size());
1856
public void testAdjacentTextObjects() {
1858
Element parent = new Element("Test");
1859
parent.appendChild("test");
1860
parent.appendChild("again");
1862
Nodes result = parent.query("text()");
1863
assertEquals(2, result.size());
1864
assertEquals("test", result.get(0).getValue());
1865
assertEquals("again", result.get(1).getValue());
1870
public void testQueryCrossesAdjacentTextObjects() {
1872
Element parent = new Element("Test");
1873
parent.appendChild("test");
1874
parent.appendChild("again");
1876
Nodes result = parent.query("node()[contains(., 'tag')]");
1877
assertEquals(2, result.size());
1878
assertEquals("test", result.get(0).getValue());
1879
assertEquals("again", result.get(1).getValue());
1884
// According to section 5.7 of the XPath 1.0 spec,
1885
// "As much character data as possible is grouped into each text
1886
// node: a text node never has an immediately following or
1887
// preceding sibling that is a text node."
1888
public void testAdjacentTextNodes2() {
1890
Element parent = new Element("Test");
1891
parent.appendChild("test");
1892
parent.appendChild("again");
1894
Nodes result = parent.query("child::text()[1]");
1895
assertEquals(2, result.size());
1896
assertEquals("test", result.get(0).getValue());
1897
assertEquals("again", result.get(1).getValue());
1902
// According to section 5.7 of the XPath 1.0 spec,
1903
// "A text node always has at least one character of data."
1904
public void testEmptyTextNodes() {
1906
Element parent = new Element("Test");
1907
parent.appendChild("");
1909
Nodes result = parent.query("child::text()");
1910
assertEquals(0, result.size());
1915
public void testEmptyTextFollowsNonEmptyText() {
1917
Element parent = new Element("parent");
1918
Text empty = new Text("");
1919
Text nonempty = new Text("value");
1920
parent.appendChild(nonempty);
1921
parent.appendChild(empty);
1922
Nodes result = parent.query("node()");
1923
assertEquals(2, result.size());
1928
public void testCountAdjacentEmptyAndNonEmptyTextNodes() {
1930
Element parent = new Element("parent");
1931
Text empty = new Text("");
1932
Text nonempty = new Text("value");
1933
parent.appendChild(nonempty);
1934
parent.appendChild(empty);
1936
Nodes result2 = parent.query("/*[count(node())=1]");
1937
assertEquals(1, result2.size());
1938
assertEquals(parent, result2.get(0));
1940
Nodes nodes1 = parent.query("node()[1]");
1941
assertEquals(2, nodes1.size());
1942
Nodes nodes2 = parent.query("node()[2]");
1943
assertEquals(0, nodes2.size());
1948
public void testAdjacentEmptyAndNonEmptyTextNodes() {
1950
Element parent = new Element("parent");
1951
Text empty = new Text("");
1952
Text nonempty = new Text("value");
1953
Text nonempty2 = new Text("value2");
1954
parent.appendChild(empty);
1955
parent.appendChild(nonempty);
1956
parent.appendChild(nonempty2);
1958
Nodes result = parent.query("node()");
1959
assertEquals(3, result.size());
1961
Nodes result2 = parent.query("/*[count(node())=1]");
1962
assertEquals(1, result2.size());
1963
assertEquals(parent, result2.get(0));
1965
Nodes nodes1 = parent.query("node()[1]");
1966
assertEquals(3, nodes1.size());
1968
Nodes nodes2 = parent.query("node()[2]");
1969
assertEquals(0, nodes2.size());
1974
public void testBadXPathExpression() {
1976
Element parent = new Element("Test");
1979
parent.query("This is not an XPath expression");
1980
fail("Allowed malformed query");
1982
catch (XPathException success) {
1983
assertNotNull(success.getMessage());
1989
public void testNaNEvaluatesToFalse() {
1991
Element root = new Element("root");
1992
Document doc = new Document(root);
1994
Nodes result = doc.query("/*[boolean(0 div 0)]");
1995
assertEquals(0, result.size());
2006
public void testPrecedingAxis() {
2008
Element body = new Element("body");
2009
Element p = new Element("p");
2010
body.appendChild(p);
2011
Element span = new Element("span");
2012
p.appendChild(span);
2013
Element div = new Element("div");
2014
body.appendChild(div);
2016
Nodes result = div.query("preceding::*[1]");
2017
assertEquals(1, result.size());
2018
assertEquals(span, result.get(0));
2023
public void testRootNodeValueIsNonEmpty() {
2025
Element root = new Element("html");
2026
Document doc = new Document(root);
2027
root.appendChild("test");
2029
Nodes result = doc.query("/*[string(/) != '']");
2030
assertEquals(1, result.size());
2031
assertEquals(root, result.get(0));
2036
public void testContextPositionForParaentlessNodeIs1() {
2038
Element root = new Element("html");
2040
Nodes result = root.query("self::*[1]");
2041
assertEquals(1, result.size());
2042
assertEquals(root, result.get(0));
2047
public void testContextSizeForParaentlessNodeIs1() {
2049
Element root = new Element("html");
2051
Nodes result = root.query("self::*[last()=1]");
2052
assertEquals(1, result.size());
2053
assertEquals(root, result.get(0));
2058
public void testLastFunction() {
2060
Element root = new Element("html");
2061
Element child1 = new Element("child1");
2062
Element child2 = new Element("child2");
2063
root.appendChild(child1);
2064
root.appendChild(child2);
2067
Nodes result = child2.query("self::*[position()=last()]");
2068
assertEquals(1, result.size());
2069
assertEquals(child2, result.get(0));
2074
public void testJaxen51() throws ParsingException, IOException {
2076
String data = "<root>\n <servlet-mapping>\n"
2077
+ " <servlet-name>DeviceInfoServlet</servlet-name>\n"
2078
+ " <url-pattern>/tools/*</url-pattern>\n"
2079
+ "</servlet-mapping>\n</root>";
2081
Builder builder = new Builder();
2082
Document doc = builder.build(data, null);
2084
Nodes result = doc.query("//*[./../servlet-name = 'DeviceInfoServlet']");
2085
assertEquals(2, result.size());
2090
public void testXPathNamespaceParentage()
2091
throws ParsingException, IOException {
2093
String input = "<!DOCTYPE doc [\n"
2094
+ "<!ATTLIST e2 xml:space (default|preserve) 'preserve'>\n"
2095
+ "<!ATTLIST e3 id ID #IMPLIED>\n"
2097
+ "<doc xmlns=\"http://www.ietf.org\" xmlns:w3c=\"http://www.w3.org\">\n"
2099
+ " <e2 xmlns=\"\">\n"
2100
+ " <e3 id=\"E3\"/>\n"
2105
Document doc = (new Builder()).build(input, null);
2106
String xpath = "(/*/* | /*/*/namespace::*)\n";
2107
Nodes result = doc.query(xpath);
2108
assertEquals(4, result.size());
2109
Element parent = (Element) result.get(0);
2110
for (int i = 1; i < 4; i++) {
2111
Namespace namespace = (Namespace) result.get(i);
2112
assertEquals(parent, namespace.getParent());
2118
public void testAttributesFollowElementsInDocumentOrder()
2119
throws ParsingException, IOException {
2121
String input = "<document>\n"
2122
+ " <e1 a='b' c='d' e='f'>\n"
2124
+ " <e3 id=\"E3\"/>\n"
2129
Document doc = (new Builder()).build(input, null);
2130
String xpath = "(/*/* | /*/*/attribute::*)\n";
2131
Nodes result = doc.query(xpath);
2132
assertEquals(4, result.size());
2133
Element parent = (Element) result.get(0);
2134
for (int i = 1; i < 4; i++) {
2135
Attribute attribute = (Attribute) result.get(i);
2136
assertEquals(parent, attribute.getParent());
2142
public void testDoubleSlashIsIncorrect() {
2144
Element root = new Element("root", "http://www.example.org");
2145
Document doc = new Document(root);
2146
root.appendChild(new Element("child"));
2147
root.appendChild("test");
2148
root.addAttribute(new Attribute("test", "test"));
2154
catch (XPathException success) {
2155
assertNotNull(success.getMessage());
2161
public void testDoubleSlashIsIncorrect2() {
2163
Element root = new Element("root", "http://www.example.org");
2164
Document doc = new Document(root);
2165
root.appendChild(new Element("child"));
2166
root.appendChild("test");
2167
root.addAttribute(new Attribute("test", "test"));
2171
fail("Queried // ");
2173
catch (XPathException success) {
2174
assertNotNull(success.getMessage());
2180
public void testWhiteSpaceIsAllowedBetweenTokens() {
2182
Element root = new Element("root", "http://www.example.org");
2183
Document doc = new Document(root);
2184
root.appendChild(new Element("child"));
2185
root.appendChild("test");
2186
root.addAttribute(new Attribute("test", "test"));
2188
Nodes nodes = doc.query("// a");
2189
assertEquals(0, nodes.size());
2194
/* public void testMassimo() throws ParsingException, IOException {
2196
Builder builder = new Builder();
2197
Document doc = builder.build("http://staff.science.uva.nl/~francesc/xpathmark/benchmark_canon.xml");
2198
Element root = doc.getRootElement();
2199
Element input_1 = root.getFirstChildElement("document_1");
2200
Element input_2 = root.getFirstChildElement("document_2");
2202
Nodes queries = root.query("child::query[starts-with('@id', 'Q')]");
2203
for (int i = 0; i < queries.size(); i++) {
2204
Element query = (Element) queries.get(i);
2205
String xpath = query.getFirstChildElement("syntax").getValue();
2206
Nodes actual = input_1.query(xpath);
2207
Elements expected = query.getChildElements();
2213
public void testJaxenIntegrationTest() throws ParsingException, IOException {
2215
Builder builder = new Builder();
2216
Document testDoc = builder.build(
2217
"http://cvs.jaxen.codehaus.org/viewrep/~raw,r=HEAD/jaxen/jaxen/xml/test/tests.xml");
2218
Elements documents = testDoc.getRootElement().getChildElements("document");
2219
for (int i = 0; i < documents.size(); i++) {
2220
Element documentElement = documents.get(i);
2221
String url = documentElement.getAttributeValue("url");
2222
Document source = builder.build(
2223
"http://cvs.jaxen.codehaus.org/viewrep/~raw,r=HEAD/jaxen/jaxen/"
2225
Elements contextElements = documentElement.getChildElements("context");
2226
for (int j = 0; j < contextElements.size(); j++) {
2227
Element contextElement = contextElements.get(j);
2229
// skip tests that use variables
2230
// because XOM doesn't support variables in
2231
// XPath expressions
2232
if (queryUsesVars(contextElement)) continue;
2234
String xpath = contextElement.getAttributeValue("select");
2235
XPathContext namespaces = getXPathContext(contextElement);
2236
Node context = source.query(xpath).get(0);
2239
Elements tests = contextElement.getChildElements("test");
2240
for (int k = 0; k < tests.size(); k++) {
2241
Element test = tests.get(k);
2243
String select = test.getAttributeValue("select");
2244
Attribute countAttribute = test.getAttribute("count");
2246
if (countAttribute != null) {
2247
count = Integer.parseInt(countAttribute.getValue());
2250
boolean exceptional = false;
2251
String exception = test.getAttributeValue("exception");
2252
if ("true".equals(exception)) {
2258
context.query(select, namespaces);
2259
fail("Evaluated " + select);
2261
catch (XPathException success) {
2262
assertNotNull(success.getMessage());
2267
Nodes results = context.query(select, namespaces);
2269
assertEquals(select, count, results.size());
2271
Elements valueOfs = test.getChildElements("valueOf");
2272
for (int v = 0; v < valueOfs.size(); v++) {
2273
Element vo = valueOfs.get(v);
2274
checkValueOf(results.get(0), vo, namespaces);
2277
catch (XPathException ex) {
2278
if (ex.getMessage().equalsIgnoreCase("XPath error: No such function document")
2279
|| ex.getMessage().equalsIgnoreCase("XPath error: No such function evaluate")) {
2289
Elements valueOfs = contextElement.getChildElements("valueOf");
2290
for (int k = 0; k < valueOfs.size(); k++) {
2291
checkValueOf(context, valueOfs.get(k), namespaces);
2299
private void checkValueOf(Node context, Element valueOf, XPathContext namespaces) {
2301
String select = valueOf.getAttributeValue("select");
2303
Nodes nodes = context.query(select, namespaces);
2304
String result = nodes.get(0).getValue();
2305
assertEquals(valueOf.getValue(), result);
2307
catch (XPathTypeException ex) {
2308
assertNotNull(ex.getMessage());
2310
catch (XPathException ex) {
2311
if (ex.getMessage().equalsIgnoreCase("XPath error: No such function document")
2312
|| ex.getMessage().equalsIgnoreCase("XPath error: No such function upper-case")
2313
|| ex.getMessage().equalsIgnoreCase("XPath error: No such function lower-case")
2314
|| ex.getMessage().equalsIgnoreCase("XPath error: No such function ends-with")
2324
private XPathContext getXPathContext(Element contextElement) {
2326
XPathContext context = new XPathContext();
2327
for (int i = 0; i < contextElement.getNamespaceDeclarationCount(); i++) {
2328
String prefix = contextElement.getNamespacePrefix(i);
2329
if (! "".equals(prefix)) {
2330
context.addNamespace(prefix, contextElement.getNamespaceURI(prefix));
2337
private boolean queryUsesVars(Element testElement) {
2339
for (int i = 0; i < testElement.getAttributeCount(); i++) {
2340
Attribute a = testElement.getAttribute(i);
2341
if ("http://jaxen.org/test-harness/var".equals(a.getNamespaceURI())) {
2349
public void testTextChildInPredicate() {
2351
Element item = new Element("item");
2352
Document doc = new Document(item);
2353
Element name = new Element("name");
2354
name.appendChild("a");
2355
item.appendChild(name);
2356
Element value = new Element("value");
2357
value.appendChild("b");
2358
item.appendChild(value);
2359
Nodes result = doc.query("/item[name/text()='a']/value");
2360
assertEquals(1, result.size());
2361
assertEquals("b", result.get(0).getValue());
2366
public void testSimpleTextChildInPredicate() {
2368
Element item = new Element("item");
2369
Document doc = new Document(item);
2370
item.appendChild("a");
2371
Nodes result = doc.query("/item[text()='a']");
2372
assertEquals(1, result.size());
2377
public void testPrecedingAxisInDocumentOrder() {
2379
Element root = new Element("root");
2382
Element a = new Element("a");
2383
root.appendChild(a);
2384
Element b = new Element("b");
2385
root.appendChild(b);
2386
Element c = new Element("c");
2389
Nodes result = b.query("preceding::*");
2390
assertEquals(2, result.size());
2391
assertEquals(a, result.get(0));
2392
assertEquals(c, result.get(1));
2397
public void testAttributeWithUnderscore() {
2399
Element a = new Element("a");
2400
Attribute foo = new Attribute("_foo", "bar");
2401
a.addAttribute(foo);
2402
Nodes results = a.query("//@_foo");
2403
assertEquals(1, results.size());
2404
assertEquals(foo, results.get(0));