1   /*
2    * $Header: /home/projects/jaxen/scm/jaxen/src/java/test/org/jaxen/XPathTestBase.java,v 1.39 2005/08/09 15:28:53 elharo Exp $
3    * $Revision: 1.39 $
4    * $Date: 2005/08/09 15:28:53 $
5    *
6    * ====================================================================
7    *
8    * Copyright (C) 2000-2002 bob mcwhirter & James Strachan.
9    * All rights reserved.
10   *
11   * Redistribution and use in source and binary forms, with or without
12   * modification, are permitted provided that the following conditions
13   * are met:
14   *
15   * 1. Redistributions of source code must retain the above copyright
16   *    notice, this list of conditions, and the following disclaimer.
17   *
18   * 2. Redistributions in binary form must reproduce the above copyright
19   *    notice, this list of conditions, and the disclaimer that follows
20   *    these conditions in the documentation and/or other materials
21   *    provided with the distribution.
22   *
23   * 3. The name "Jaxen" must not be used to endorse or promote products
24   *    derived from this software without prior written permission.  For
25   *    written permission, please contact license@jaxen.org.
26   *
27   * 4. Products derived from this software may not be called "Jaxen", nor
28   *    may "Jaxen" appear in their name, without prior written permission
29   *    from the Jaxen Project Management (pm@jaxen.org).
30   *
31   * In addition, we request (but do not require) that you include in the
32   * end-user documentation provided with the redistribution and/or in the
33   * software itself an acknowledgement equivalent to the following:
34   *     "This product includes software developed by the
35   *      Jaxen Project (http://www.jaxen.org/)."
36   * Alternatively, the acknowledgment may be graphical using the logos
37   * available at http://www.jaxen.org/
38   *
39   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
40   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
41   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
42   * DISCLAIMED.  IN NO EVENT SHALL THE Jaxen AUTHORS OR THE PROJECT
43   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
45   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
46   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
47   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
48   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
49   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50   * SUCH DAMAGE.
51   *
52   * ====================================================================
53   * This software consists of voluntary contributions made by many
54   * individuals on behalf of the Jaxen Project and was originally
55   * created by bob mcwhirter <bob@werken.com> and
56   * James Strachan <jstrachan@apache.org>.  For more information on the
57   * Jaxen Project, please see <http://www.jaxen.org/>.
58   *
59   * $Id: XPathTestBase.java,v 1.39 2005/08/09 15:28:53 elharo Exp $
60   */
61  
62  
63  package org.jaxen;
64  
65  import junit.framework.TestCase;
66  import org.jaxen.function.StringFunction;
67  import org.jaxen.saxpath.helpers.XPathReaderFactory;
68  import org.jaxen.pattern.Pattern;
69  
70  import java.util.ArrayList;
71  import java.util.Iterator;
72  import java.util.List;
73  
74  public abstract class XPathTestBase extends TestCase
75  {
76      protected static String VAR_URI   = "http://jaxen.org/test-harness/var";
77      protected static String TESTS_XML = "xml/test/tests.xml";
78  
79      protected static boolean verbose = false;
80      protected static boolean debug = false;
81      private ContextSupport contextSupport;
82  
83      protected XPathTestBase(String name)
84      {
85          super(name);
86      }
87  
88      public void setUp()
89      {
90          this.contextSupport = null;
91          System.setProperty(XPathReaderFactory.DRIVER_PROPERTY,
92                  "");
93          log("-----------------------------");
94      }
95  
96      public void log(String text)
97      {
98          log(verbose,
99                  text);
100     }
101 
102     private void log(boolean actualVerbose,
103                     String text)
104     {
105         if (actualVerbose) System.out.println(text);
106     }
107 
108     private void assertCountXPath(int expectedSize, Object context, String xpathStr) throws JaxenException
109     {
110         assertCountXPath2(expectedSize, context, xpathStr);
111     }
112 
113     private Object assertCountXPath2(int expectedSize, Object context, String xpathStr) throws JaxenException
114     {
115         log(debug,
116                 "  Select :: " + xpathStr);
117         BaseXPath xpath = new BaseXPath(xpathStr);
118         List results = xpath.selectNodes(getContext(context));
119         log(debug,
120                 "    Expected Size :: " + expectedSize);
121         log(debug,
122                 "    Result Size   :: " + results.size());
123         if (expectedSize != results.size())
124         {
125             log(debug,
126                     "      ## FAILED");
127             log(debug,
128                     "      ## xpath: " + xpath + " = " + xpath.debug());
129             Iterator resultIter = results.iterator();
130             while (resultIter.hasNext())
131             {
132                 log(debug,
133                         "      --> " + resultIter.next());
134             }
135         }
136         assertEquals(xpathStr,
137                 expectedSize,
138                 results.size());
139         if (expectedSize > 0)
140         {
141             return results.get(0);
142         }
143         return null;
144     }
145 
146     private void assertInvalidXPath(Object context, String xpathStr)
147     {
148         try
149         {
150             log(debug,
151                     "  Select :: " + xpathStr);
152             BaseXPath xpath = new BaseXPath(xpathStr);
153             List results = xpath.selectNodes(getContext(context));
154             log(debug,
155                     "    Result Size   :: " + results.size());
156             fail("An exception was expected.");
157         }
158         catch (JaxenException e)
159         {
160             log(debug, "    Caught expected exception " + e.getMessage());
161         }
162     }
163 
164     private void assertValueOfXPath(String expected, Object context, String xpathStr) throws JaxenException
165     {
166             BaseXPath xpath = new BaseXPath(xpathStr);
167             Object node = xpath.evaluate(getContext(context));
168             String result = StringFunction.evaluate(node,
169                     getNavigator());
170             log(debug,
171                     "  Select :: " + xpathStr);
172             log(debug,
173                     "    Expected :: " + expected);
174             log(debug,
175                     "    Result   :: " + result);
176             if (!expected.equals(result))
177             {
178                 log(debug,
179                         "      ## FAILED");
180                 log(debug,
181                         "      ## xpath: " + xpath + " = " + xpath.debug());
182             }
183             assertEquals(xpathStr,
184                     expected,
185                     result);
186         }
187 
188     private Context getContext(Object contextNode)
189     {
190         Context context = new Context(getContextSupport());
191         List list = new ArrayList(1);
192         list.add(contextNode);
193         context.setNodeSet(list);
194         return context;
195     }
196 
197     private ContextSupport getContextSupport()
198     {
199         if (this.contextSupport == null)
200         {
201             this.contextSupport = new ContextSupport(new SimpleNamespaceContext(),
202                     XPathFunctionContext.getInstance(),
203                     new SimpleVariableContext(),
204                     getNavigator());
205         }
206         return this.contextSupport;
207     }
208 
209     protected abstract Navigator getNavigator();
210 
211     // be more specific; throws Exception????
212     protected abstract Object getDocument(String url) throws Exception;
213 
214     public void testGetNodeType() throws FunctionCallException, UnsupportedAxisException
215     {
216         Navigator nav = getNavigator();
217         Object document = nav.getDocument("xml/testNamespaces.xml");
218         int count = 0;
219         Iterator descendantOrSelfAxisIterator = nav.getDescendantOrSelfAxisIterator(document);
220         while (descendantOrSelfAxisIterator.hasNext())
221         {
222             Object node = descendantOrSelfAxisIterator.next();
223             Iterator namespaceAxisIterator = nav.getNamespaceAxisIterator(node);
224             while (namespaceAxisIterator.hasNext())
225             {
226                 count++;
227                 assertEquals("Node type mismatch", Pattern.NAMESPACE_NODE, nav.getNodeType(namespaceAxisIterator.next()));
228             }
229         }
230         assertEquals(25, count);
231     }
232 
233 
234     /* test for jaxen-24
235     */
236     public void testJaxen24() throws JaxenException
237     {
238         Navigator nav = getNavigator();
239         String url = "xml/jaxen24.xml";
240         log("Document [" + url + "]");
241         Object document = nav.getDocument(url);
242         XPath contextpath = new BaseXPath("/body/div", nav);
243         log("Initial Context :: " + contextpath);
244         List list = contextpath.selectNodes(document);
245         Iterator iter = list.iterator();
246         while (iter.hasNext())
247         {
248             Object context = iter.next();
249             assertCountXPath(1, context, "preceding::*[1]");
250             assertValueOfXPath("span", context, "local-name(preceding::*[1])");
251         }
252     }
253 
254     /* jaxen-58
255     */
256     public void testJaxen58() throws JaxenException
257     {
258         Navigator nav = getNavigator();
259         String url = "xml/jaxen24.xml";
260         log("Document [" + url + "]");
261         Object document = nav.getDocument(url);
262         XPath contextpath = new BaseXPath("/", nav);
263         log("Initial Context :: " + contextpath);
264         List list = contextpath.selectNodes(document);
265         Iterator iter = list.iterator();
266         while (iter.hasNext())
267         {
268             Object context = iter.next();
269             assertCountXPath(0, context, "//preceding::x");
270             assertCountXPath(0, context, "//following::x");
271             assertCountXPath(0, context, "/descendant::*/preceding::x");
272             assertCountXPath(0, context, "/descendant::node()/preceding::x");
273         }
274     }
275 
276     /* test for jaxen-3
277     */
278     public void testJaxen3() throws JaxenException
279     {
280         Navigator nav = getNavigator();
281         String url = "xml/simple.xml";
282         log("Document [" + url + "]");
283         Object document = nav.getDocument(url);
284         XPath contextpath = new BaseXPath("/", nav);
285         log("Initial Context :: " + contextpath);
286         List list = contextpath.selectNodes(document);
287         Iterator iter = list.iterator();
288         while (iter.hasNext())
289         {
290             Object context = iter.next();
291             assertValueOfXPath("abd", context, "string()");
292         }
293     }
294 
295     public void testStringFunction1() throws JaxenException
296     {
297         Navigator nav = getNavigator();
298         String url = "xml/simple.xml";
299         log("Document [" + url + "]");
300         Object document = nav.getDocument(url);
301         XPath contextpath = new BaseXPath("/root", nav);
302         log("Initial Context :: " + contextpath);
303         List list = contextpath.selectNodes(document);
304         Iterator iter = list.iterator();
305         while (iter.hasNext())
306         {
307             Object context = iter.next();
308             assertValueOfXPath("abd", context, "string()");
309         }
310     }
311 
312     public void testStringFunction2() throws JaxenException
313     {
314         Navigator nav = getNavigator();
315         String url = "xml/simple.xml";
316         log("Document [" + url + "]");
317         Object document = nav.getDocument(url);
318         XPath contextpath = new BaseXPath("/root/a", nav);
319         log("Initial Context :: " + contextpath);
320         List list = contextpath.selectNodes(document);
321         Iterator iter = list.iterator();
322         while (iter.hasNext())
323         {
324             Object context = iter.next();
325             assertValueOfXPath("a", context, "string()");
326         }
327     }
328 
329     public void testStringFunction3() throws JaxenException
330     {
331         Navigator nav = getNavigator();
332         String url = "xml/simple.xml";
333         log("Document [" + url + "]");
334         Object document = nav.getDocument(url);
335         XPath contextpath = new BaseXPath("/root/c", nav);
336         log("Initial Context :: " + contextpath);
337         List list = contextpath.selectNodes(document);
338         Iterator iter = list.iterator();
339         while (iter.hasNext())
340         {
341             Object context = iter.next();
342             assertValueOfXPath("d", context, "string()");
343         }
344     }
345 
346     /* test for jaxen-3
347     */
348     public void testJaxen3dupe() throws JaxenException
349     {
350         Navigator nav = getNavigator();
351         String url = "xml/jaxen3.xml";
352         log("Document [" + url + "]");
353         Object document = nav.getDocument(url);
354         XPath contextpath = new BaseXPath("/", nav);
355         log("Initial Context :: " + contextpath);
356         List list = contextpath.selectNodes(document);
357         Iterator iter = list.iterator();
358         while (iter.hasNext())
359         {
360             Object context = iter.next();
361             assertCountXPath(1, context, "/Configuration/hostname/attrlist/hostname[. = 'CE-A'] ");
362         }
363     }
364 
365     /* parser test cases all of which should fail
366     */
367     public void testForParserErrors() throws JaxenException
368     {
369         Navigator nav = getNavigator();
370         String url = "xml/numbers.xml";
371         log("Document [" + url + "]");
372         Object document = nav.getDocument(url);
373         XPath contextpath = new BaseXPath("/", nav);
374         log("Initial Context :: " + contextpath);
375         List list = contextpath.selectNodes(document);
376         Iterator iter = list.iterator();
377         while (iter.hasNext())
378         {
379             Object context = iter.next();
380             /* repeated xpaths, jaxen-35
381             */
382             assertInvalidXPath(context, "/numbers numbers");
383             /* invalid xpath, jaxen-34
384             */
385             assertInvalidXPath(context, "/a/b[c > d]efg");
386             /* invalid xpath, jaxen-27
387             */
388             assertInvalidXPath(context, "/inv/child::");
389             /* invalid xpath, jaxen-26
390             */
391             assertInvalidXPath(context, "/invoice/@test[abcd");
392             assertInvalidXPath(context, "/invoice/@test[abcd > x");
393             /* unterminated string
394             */
395             assertInvalidXPath(context, "string-length('a");
396             /* various edge cases where code threw no exception
397             */
398             assertInvalidXPath(context, "/descendant::()");
399             assertInvalidXPath(context, "(1 + 1");
400         }
401     }
402 
403     /* test cases for the use of underscores in names
404     */
405     public void testUnderscoresInNames() throws JaxenException
406     {
407         Navigator nav = getNavigator();
408         String url = "xml/underscore.xml";
409         log("Document [" + url + "]");
410         Object document = nav.getDocument(url);
411         XPath contextpath = new BaseXPath("/", nav);
412         log("Initial Context :: " + contextpath);
413         List list = contextpath.selectNodes(document);
414         Iterator iter = list.iterator();
415         while (iter.hasNext())
416         {
417             Object context = iter.next();
418             assertCountXPath(1, context, "/root/@a");
419             assertCountXPath(1, context, "/root/@_a");
420             assertCountXPath(1, context, "/root/b");
421             assertCountXPath(1, context, "/root/_b");
422             assertValueOfXPath("1", context, "/root/@a");
423             assertValueOfXPath("2", context, "/root/@_a");
424             assertValueOfXPath("1", context, "/root/b");
425             assertValueOfXPath("2", context, "/root/_b");
426         }
427     }
428 
429     /* test cases for the use of = with node-sets
430     */
431     public void testNodesetEqualsString() throws JaxenException
432     {
433         Navigator nav = getNavigator();
434         String url = "xml/web.xml";
435         log("Document [" + url + "]");
436         Object document = nav.getDocument(url);
437         XPath contextpath = new BaseXPath("/", nav);
438         log("Initial Context :: " + contextpath);
439         List list = contextpath.selectNodes(document);
440         Iterator iter = list.iterator();
441         while (iter.hasNext())
442         {
443             Object context = iter.next();
444             assertValueOfXPath("true", context, "/web-app/servlet/servlet-name = 'file'");
445             assertValueOfXPath("true", context, "/web-app/servlet/servlet-name = 'snoop'");
446         }
447     }
448 
449     public void testNodesetEqualsNumber() throws JaxenException
450     {
451         Navigator nav = getNavigator();
452         String url = "xml/numbers.xml";
453         log("Document [" + url + "]");
454         Object document = nav.getDocument(url);
455         XPath contextpath = new BaseXPath("/", nav);
456         log("Initial Context :: " + contextpath);
457         List list = contextpath.selectNodes(document);
458         Iterator iter = list.iterator();
459         while (iter.hasNext())
460         {
461             Object context = iter.next();
462             assertValueOfXPath("true", context, "/numbers/set/nr = '-3'");
463             assertValueOfXPath("true", context, "/numbers/set/nr = -3");
464             assertValueOfXPath("true", context, "/numbers/set/nr = 24");
465             assertValueOfXPath("true", context, "/numbers/set/nr/@value = '9999'");
466             assertValueOfXPath("true", context, "/numbers/set/nr/@value = 9999.0");
467             assertValueOfXPath("true", context, "/numbers/set/nr/@value = 66");
468         }
469     }
470 
471     /* test basic math...
472     */
473     public void testArithmetic() throws JaxenException
474     {
475         Navigator nav = getNavigator();
476         String url = "xml/numbers.xml";
477         log("Document [" + url + "]");
478         Object document = nav.getDocument(url);
479         XPath contextpath = new BaseXPath("/", nav);
480         log("Initial Context :: " + contextpath);
481         List list = contextpath.selectNodes(document);
482         Iterator iter = list.iterator();
483         while (iter.hasNext())
484         {
485             Object context = iter.next();
486             assertValueOfXPath("true", context, "(8 * 2 + 1) = 17");
487             assertValueOfXPath("true", context, "(1 + 8 * 2) = 17");
488             assertValueOfXPath("true", context, "(7 - 3 + 1) = 5");
489             assertValueOfXPath("true", context, "(8 - 4 + 5 - 6) = 3");
490             /* left-assoc tests, comments show WRONG evaluation
491             */
492             /* 3 - 2 - 1 != 2
493             */
494             assertValueOfXPath("0", context, "3 - 2 - 1");
495             /* 8 div 4 div 2 != 4
496             */
497             assertValueOfXPath("1", context, "8 div 4 div 2");
498             /* 3 mod 5 mod 7 != 1
499             */
500             assertValueOfXPath("3", context, "3 mod 7 mod 5");
501             /* 1=(2=2) is true
502             */
503             assertValueOfXPath("false", context, "1 = 2 = 2");
504             /*  2!=(3!=1) => 2!=1 => true, (2!=3)!=1 => 1!=1 => false
505             */
506             assertValueOfXPath("false", context, "2 != 3 != 1");
507             /* 3 > (2 > 1) is true
508             */
509             assertValueOfXPath("false", context, "3 > 2 > 1");
510             /* 3 >= (2 >= 2) is true
511             */
512             assertValueOfXPath("false", context, "3 >= 2 >= 2");
513             /* 1 < (2 < 3) is false
514             */
515             assertValueOfXPath("true", context, "1 < 2 < 3");
516             /* 0 <= (2 <= 3) is true
517             */
518             assertValueOfXPath("true", context, "2 <= 2 <= 3");
519         }
520     }
521 
522     /* test cases for preceding axis with different node types
523     */
524     public void testPrecedingSiblingAxis() throws JaxenException
525     {
526         Navigator nav = getNavigator();
527         String url = "xml/pi2.xml";
528         log("Document [" + url + "]");
529         Object document = nav.getDocument(url);
530         XPath contextpath = new BaseXPath("/a/c", nav);
531         log("Initial Context :: " + contextpath);
532         List list = contextpath.selectNodes(document);
533         Iterator iter = list.iterator();
534         while (iter.hasNext())
535         {
536             Object context = iter.next();
537             assertCountXPath(1, context, "//processing-instruction()");
538             assertCountXPath(1, context, "preceding-sibling::*");
539             assertCountXPath(5, context, "preceding-sibling::node()");
540             assertCountXPath(1, context, "preceding-sibling::*[1]");
541             assertCountXPath(1, context, "preceding-sibling::processing-instruction()");
542             assertValueOfXPath("order-by=\"x\"", context, "preceding-sibling::processing-instruction()");
543             assertValueOfXPath("foo", context, "preceding-sibling::*[1]");
544             assertValueOfXPath("order-by=\"x\"", context, "preceding-sibling::node()[2]");
545         }
546     }
547 
548     public void testVariableLookup() throws JaxenException
549     {
550         Navigator nav = getNavigator();
551         String url = "xml/id.xml";
552         log("Document [" + url + "]");
553         Object document = nav.getDocument(url);
554         XPath contextpath = new BaseXPath("/", nav);
555         log("Initial Context :: " + contextpath);
556         List list = contextpath.selectNodes(document);
557         SimpleVariableContext varContext = new SimpleVariableContext();
558         varContext.setVariableValue(null, "foobar", "foobar");
559         varContext.setVariableValue(null, "foo", "foo");
560         getContextSupport().setVariableContext(varContext);
561         Iterator iter = list.iterator();
562         while (iter.hasNext())
563         {
564             Object context = iter.next();
565             assertValueOfXPath("foobar", context, "$foobar");
566             assertCountXPath(1, context, "/foo[@id=$foobar]");
567             assertCountXPath(0, context, "/foo[@id='$foobar']");
568             assertCountXPath(1, context, "/foo[concat($foo, 'bar')=@id]");
569             assertCountXPath(0, context, "CD_Library/artist[@name=$artist]");
570         }
571     }
572 
573     public void testAttributeParent() throws JaxenException
574     {
575         Navigator nav = getNavigator();
576         String url = "xml/id.xml";
577         log("Document [" + url + "]");
578         Object document = nav.getDocument(url);
579         XPath contextpath = new BaseXPath("/", nav);
580         log("Initial Context :: " + contextpath);
581         List list = contextpath.selectNodes(document);
582         Iterator iter = list.iterator();
583         while (iter.hasNext())
584         {
585             Object context = iter.next();
586             /* attributes have a parent: their element
587             */
588             assertCountXPath(1, context, "/foo/@id/parent::foo");
589         }
590     }
591 
592     /* attributes can also be used as context nodes
593     */
594     public void testAttributeAsContext() throws JaxenException
595     {
596         Navigator nav = getNavigator();
597         String url = "xml/id.xml";
598         log("Document [" + url + "]");
599         Object document = nav.getDocument(url);
600         XPath contextpath = new BaseXPath("/foo/@id", nav);
601         log("Initial Context :: " + contextpath);
602         List list = contextpath.selectNodes(document);
603         Iterator iter = list.iterator();
604         while (iter.hasNext())
605         {
606             Object context = iter.next();
607             assertCountXPath(1, context, "parent::foo");
608         }
609     }
610 
611     public void testid53992() throws JaxenException
612     {
613         Navigator nav = getNavigator();
614         String url = "xml/pi.xml";
615         log("Document [" + url + "]");
616         Object document = nav.getDocument(url);
617         XPath contextpath = new BaseXPath("/", nav);
618         log("Initial Context :: " + contextpath);
619         List list = contextpath.selectNodes(document);
620         Iterator iter = list.iterator();
621         while (iter.hasNext())
622         {
623             Object context = iter.next();
624             assertCountXPath(3, context, "//processing-instruction()");
625             assertCountXPath(2, context, "//processing-instruction('cheese')");
626                 Object result = assertCountXPath2(1, context, "//processing-instruction('toast')");
627                 assertValueOfXPath("is tasty", result, "string()");
628             }
629             }
630 
631     /* test evaluate() extension function
632     */
633     public void testid54032() throws JaxenException
634     {
635         Navigator nav = getNavigator();
636         String url = "xml/evaluate.xml";
637         log("Document [" + url + "]");
638         Object document = nav.getDocument(url);
639         XPath contextpath = new BaseXPath("/", nav);
640         log("Initial Context :: " + contextpath);
641         List list = contextpath.selectNodes(document);
642         Iterator iter = list.iterator();
643         while (iter.hasNext())
644         {
645             Object context = iter.next();
646             assertCountXPath(3, context, "evaluate('//jumps/*')");
647             assertCountXPath(1, context, "evaluate('//jumps/object/dog')");
648             assertCountXPath(0, context, "evaluate('//jumps/object')/evaluate");
649             assertCountXPath(1, context, "evaluate('//jumps/object')/dog");
650             assertCountXPath(1, context, "evaluate('//jumps/*')/dog");
651             assertCountXPath(1, context, "//metatest[ evaluate(@select) = . ]");
652         }
653     }
654 
655     public void testid54082() throws JaxenException
656     {
657         Navigator nav = getNavigator();
658         String url = "xml/numbers.xml";
659         log("Document [" + url + "]");
660         Object document = nav.getDocument(url);
661         XPath contextpath = new BaseXPath("/numbers/set[1]", nav);
662         log("Initial Context :: " + contextpath);
663         List list = contextpath.selectNodes(document);
664         Iterator iter = list.iterator();
665         while (iter.hasNext())
666         {
667             Object context = iter.next();
668             assertCountXPath(1, context, "*[-3 = .]");
669             assertValueOfXPath("true", context, "54 < *");
670             assertValueOfXPath("true", context, "55 <= *");
671             assertValueOfXPath("false", context, "69 < *");
672             assertValueOfXPath("true", context, "-2 > *");
673             assertValueOfXPath("true", context, "-3 >= *");
674             assertValueOfXPath("false", context, "-4 >= *");
675         }
676     }
677 
678     /* TODO
679     This context should work, but needs a fixed version of saxpath to parse the right-hand side
680     of the greater-than expression.
681     <context select="/numbers/set[2]">
682       <valueOf select="1 &gt; nr/@value">false</valueOf>
683       <valueOf select="55 &gt; nr/@value">false</valueOf>
684       <valueOf select="55 &gt;= nr/@value">true</valueOf>
685       <valueOf select="1000000 &gt; nr/@value">true</valueOf>
686     </context>
687     
688     */
689     /* test sibling axes 
690     */
691     public void testid54145() throws JaxenException
692     {
693         Navigator nav = getNavigator();
694         String url = "xml/axis.xml";
695         log("Document [" + url + "]");
696         Object document = nav.getDocument(url);
697         XPath contextpath = new BaseXPath("/root", nav);
698         log("Initial Context :: " + contextpath);
699         List list = contextpath.selectNodes(document);
700         Iterator iter = list.iterator();
701         while (iter.hasNext())
702         {
703             Object context = iter.next();
704             assertCountXPath(0, context, "preceding-sibling::*");
705         }
706     }
707 
708     public void testid54156() throws JaxenException
709     {
710         Navigator nav = getNavigator();
711         String url = "xml/axis.xml";
712         log("Document [" + url + "]");
713         Object document = nav.getDocument(url);
714         XPath contextpath = new BaseXPath("/root/a/a.3", nav);
715         log("Initial Context :: " + contextpath);
716         List list = contextpath.selectNodes(document);
717         Iterator iter = list.iterator();
718         while (iter.hasNext())
719         {
720             Object context = iter.next();
721             assertCountXPath(2, context, "preceding::*");
722         }
723     }
724 
725     public void testid54168() throws JaxenException
726     {
727         Navigator nav = getNavigator();
728         String url = "xml/axis.xml";
729         log("Document [" + url + "]");
730         Object document = nav.getDocument(url);
731         XPath contextpath = new BaseXPath("/root/a/a.3", nav);
732         log("Initial Context :: " + contextpath);
733         List list = contextpath.selectNodes(document);
734         Iterator iter = list.iterator();
735         while (iter.hasNext())
736         {
737             Object context = iter.next();
738             assertCountXPath(2, context, "preceding-sibling::*");
739         }
740     }
741 
742     public void testid54180() throws JaxenException
743     {
744         Navigator nav = getNavigator();
745         String url = "xml/axis.xml";
746         log("Document [" + url + "]");
747         Object document = nav.getDocument(url);
748         XPath contextpath = new BaseXPath("/", nav);
749         log("Initial Context :: " + contextpath);
750         List list = contextpath.selectNodes(document);
751         Iterator iter = list.iterator();
752         while (iter.hasNext())
753         {
754             Object context = iter.next();
755             assertValueOfXPath("a.2", context, "name(/root/a/a.3/preceding-sibling::*[1])");
756             assertValueOfXPath("a.1", context, "name(/root/a/a.3/preceding-sibling::*[2])");
757         }
758     }
759 
760     public void testid54197() throws JaxenException
761     {
762         Navigator nav = getNavigator();
763         String url = "xml/axis.xml";
764         log("Document [" + url + "]");
765         Object document = nav.getDocument(url);
766         XPath contextpath = new BaseXPath("/", nav);
767         log("Initial Context :: " + contextpath);
768         List list = contextpath.selectNodes(document);
769         Iterator iter = list.iterator();
770         while (iter.hasNext())
771         {
772             Object context = iter.next();
773             assertValueOfXPath("a.4", context, "name(/root/a/a.3/following-sibling::*[1])");
774             assertValueOfXPath("a.5", context, "name(/root/a/a.3/following-sibling::*[2])");
775         }
776     }
777 
778     public void testid54219() throws JaxenException
779     {
780         Navigator nav = getNavigator();
781         String url = "xml/web.xml";
782         log("Document [" + url + "]");
783         Object document = nav.getDocument(url);
784         XPath contextpath = new BaseXPath("/", nav);
785         log("Initial Context :: " + contextpath);
786         List list = contextpath.selectNodes(document);
787         Iterator iter = list.iterator();
788         while (iter.hasNext())
789         {
790             Object context = iter.next();
791             assertValueOfXPath("snoop", context, "/web-app/servlet[1]/servlet-name");
792             assertValueOfXPath("snoop", context, "/web-app/servlet[1]/servlet-name/text()");
793             assertValueOfXPath("file", context, "/web-app/servlet[2]/servlet-name");
794             assertValueOfXPath("file", context, "/web-app/servlet[2]/servlet-name/text()");
795         }
796     }
797 
798     public void testid54249() throws JaxenException
799     {
800         Navigator nav = getNavigator();
801         String url = "xml/web.xml";
802         log("Document [" + url + "]");
803         Object document = nav.getDocument(url);
804         XPath contextpath = new BaseXPath("/web-app/servlet[1]", nav);
805         log("Initial Context :: " + contextpath);
806         List list = contextpath.selectNodes(document);
807         Iterator iter = list.iterator();
808         while (iter.hasNext())
809         {
810             Object context = iter.next();
811             assertValueOfXPath("snoop", context, "servlet-name");
812             assertValueOfXPath("snoop", context, "servlet-name/text()");
813         }
814     }
815 
816     public void testid54266() throws JaxenException
817     {
818         Navigator nav = getNavigator();
819         String url = "xml/web.xml";
820         log("Document [" + url + "]");
821         Object document = nav.getDocument(url);
822         XPath contextpath = new BaseXPath("/web-app/servlet[2]/servlet-name", nav);
823         log("Initial Context :: " + contextpath);
824         List list = contextpath.selectNodes(document);
825         Iterator iter = list.iterator();
826         while (iter.hasNext())
827         {
828             Object context = iter.next();
829             assertCountXPath(3, context, "preceding::*");
830         }
831     }
832 
833     public void testid54278() throws JaxenException
834     {
835         Navigator nav = getNavigator();
836         String url = "xml/web.xml";
837         log("Document [" + url + "]");
838         Object document = nav.getDocument(url);
839         XPath contextpath = new BaseXPath("/web-app/servlet[2]/servlet-name", nav);
840         log("Initial Context :: " + contextpath);
841         List list = contextpath.selectNodes(document);
842         Iterator iter = list.iterator();
843         while (iter.hasNext())
844         {
845             Object context = iter.next();
846             assertCountXPath(13, context, "following::*");
847         }
848     }
849 
850     /* test name
851     */
852     public void testid54298() throws JaxenException
853     {
854         Navigator nav = getNavigator();
855         String url = "xml/web.xml";
856         log("Document [" + url + "]");
857         Object document = nav.getDocument(url);
858         XPath contextpath = new BaseXPath("/", nav);
859         log("Initial Context :: " + contextpath);
860         List list = contextpath.selectNodes(document);
861         Iterator iter = list.iterator();
862         while (iter.hasNext())
863         {
864             Object context = iter.next();
865                 Object result = assertCountXPath2(1, context, "*");
866                 assertValueOfXPath("web-app", result, "name()");
867             /* NOTE that the child::node() tests only work if the
868               XML document does not comments or PIs
869 
870             */
871             result = assertCountXPath2(1, context, "./*");
872                 assertValueOfXPath("web-app", result, "name()");
873             result = assertCountXPath2(1, context, "child::*");
874                 assertValueOfXPath("web-app", result, "name()");
875             result = assertCountXPath2(1, context, "/*");
876                 assertValueOfXPath("web-app", result, "name()");
877             result = assertCountXPath2(1, context, "/child::node()");
878                 assertValueOfXPath("web-app", result, "name(.)");
879             result = assertCountXPath2(1, context, "child::node()");
880                 assertValueOfXPath("web-app", result, "name(.)");
881             /* empty names
882             */
883             assertValueOfXPath("", context, "name()");
884             assertValueOfXPath("", context, "name(.)");
885             assertValueOfXPath("", context, "name(parent::*)");
886             assertValueOfXPath("", context, "name(/)");
887             assertValueOfXPath("", context, "name(/.)");
888             assertValueOfXPath("", context, "name(/self::node())");
889             /* name of root elemet
890             */
891             assertValueOfXPath("web-app", context, "name(node())");
892             assertValueOfXPath("web-app", context, "name(/node())");
893             assertValueOfXPath("web-app", context, "name(/*)");
894             assertValueOfXPath("web-app", context, "name(/child::*)");
895             assertValueOfXPath("web-app", context, "name(/child::node())");
896             assertValueOfXPath("web-app", context, "name(/child::node())");
897             assertValueOfXPath("web-app", context, "name(child::node())");
898             assertValueOfXPath("web-app", context, "name(./*)");
899             assertValueOfXPath("web-app", context, "name(*)");
900         }
901     }
902 
903     public void testid54467() throws JaxenException
904     {
905         Navigator nav = getNavigator();
906         String url = "xml/web.xml";
907         log("Document [" + url + "]");
908         Object document = nav.getDocument(url);
909         XPath contextpath = new BaseXPath("/*", nav);
910         log("Initial Context :: " + contextpath);
911         List list = contextpath.selectNodes(document);
912         Iterator iter = list.iterator();
913         while (iter.hasNext())
914         {
915             Object context = iter.next();
916             /* empty names
917             */
918             assertValueOfXPath("", context, "name(..)");
919             assertValueOfXPath("", context, "name(parent::node())");
920             assertValueOfXPath("", context, "name(parent::*)");
921             /* name of root elemet
922             */
923             assertValueOfXPath("web-app", context, "name()");
924             assertValueOfXPath("web-app", context, "name(.)");
925             assertValueOfXPath("web-app", context, "name(../*)");
926             assertValueOfXPath("web-app", context, "name(../child::node())");
927         }
928     }
929 
930     /* test predicates
931     */
932     public void testid54522() throws JaxenException
933     {
934         Navigator nav = getNavigator();
935         String url = "xml/nitf.xml";
936         log("Document [" + url + "]");
937         Object document = nav.getDocument(url);
938         XPath contextpath = new BaseXPath("/nitf/head/docdata", nav);
939         log("Initial Context :: " + contextpath);
940         List list = contextpath.selectNodes(document);
941         Iterator iter = list.iterator();
942         while (iter.hasNext())
943         {
944             Object context = iter.next();
945             assertCountXPath(1, context, "doc-id[@regsrc='AP' and @id-string='D76UIMO80']");
946         }
947     }
948 
949     public void testid54534() throws JaxenException
950     {
951         Navigator nav = getNavigator();
952         String url = "xml/nitf.xml";
953         log("Document [" + url + "]");
954         Object document = nav.getDocument(url);
955         XPath contextpath = new BaseXPath("/nitf/head", nav);
956         log("Initial Context :: " + contextpath);
957         List list = contextpath.selectNodes(document);
958         Iterator iter = list.iterator();
959         while (iter.hasNext())
960         {
961             Object context = iter.next();
962             assertCountXPath(1, context, "meta[@name='ap-cycle']");
963             assertCountXPath(1, context, "meta[@content='AP']");
964             assertCountXPath(8, context, "meta[@name and @content]");
965             assertCountXPath(1, context, "meta[@name='ap-cycle' and @content='AP']");
966             assertCountXPath(7, context, "meta[@name != 'ap-cycle']");
967         }
968     }
969 
970     public void testid54570() throws JaxenException
971     {
972         Navigator nav = getNavigator();
973         String url = "xml/nitf.xml";
974         log("Document [" + url + "]");
975         Object document = nav.getDocument(url);
976         XPath contextpath = new BaseXPath("/", nav);
977         log("Initial Context :: " + contextpath);
978         List list = contextpath.selectNodes(document);
979         Iterator iter = list.iterator();
980         while (iter.hasNext())
981         {
982             Object context = iter.next();
983             assertCountXPath(1, context, "/nitf/head/meta[@name='ap-cycle']");
984             assertCountXPath(1, context, "/nitf/head/meta[@content='AP']");
985             assertCountXPath(8, context, "/nitf/head/meta[@name and @content]");
986             assertCountXPath(1, context, "/nitf/head/meta[@name='ap-cycle' and @content='AP']");
987             assertCountXPath(7, context, "/nitf/head/meta[@name != 'ap-cycle']");
988         }
989     }
990 
991     public void testid54614() throws JaxenException
992     {
993         Navigator nav = getNavigator();
994         String url = "xml/moreover.xml";
995         log("Document [" + url + "]");
996         Object document = nav.getDocument(url);
997         XPath contextpath = new BaseXPath("/", nav);
998         log("Initial Context :: " + contextpath);
999         List list = contextpath.selectNodes(document);
1000         Iterator iter = list.iterator();
1001         while (iter.hasNext())
1002         {
1003             Object context = iter.next();
1004             assertCountXPath(1, context, "/child::node()");
1005             assertCountXPath(1, context, "/*");
1006             assertCountXPath(20, context, "/*/article");
1007             assertCountXPath(221, context, "//*");
1008             assertCountXPath(20, context, "//*[local-name()='article']");
1009             assertCountXPath(20, context, "//article");
1010             assertCountXPath(20, context, "/*/*[@code]");
1011             assertCountXPath(1, context, "/moreovernews/article[@code='13563275']");
1012                 BaseXPath xpath = new BaseXPath("/moreovernews/article[@code='13563275']");
1013                 List results = xpath.selectNodes(getContext(context));
1014                 Object result = results.get(0);
1015                 assertValueOfXPath("http://c.moreover.com/click/here.pl?x13563273", result, "url");
1016             xpath = new BaseXPath("/*/article[@code='13563275']");
1017             results = xpath.selectNodes(getContext(context));
1018             result = results.get(0);
1019                 assertValueOfXPath("http://c.moreover.com/click/here.pl?x13563273", result, "url");
1020             xpath = new BaseXPath("//article[@code='13563275']");
1021             results = xpath.selectNodes(getContext(context));
1022             result = results.get(0);
1023                 assertValueOfXPath("http://c.moreover.com/click/here.pl?x13563273", result, "url");
1024             xpath = new BaseXPath("//*[@code='13563275']");
1025             results = xpath.selectNodes(getContext(context));
1026             result = results.get(0);
1027                 assertValueOfXPath("http://c.moreover.com/click/here.pl?x13563273", result, "url");
1028             xpath = new BaseXPath("/child::node()/child::node()[@code='13563275']");
1029             results = xpath.selectNodes(getContext(context));
1030             result = results.get(0);
1031                 assertValueOfXPath("http://c.moreover.com/click/here.pl?x13563273", result, "url");
1032             xpath = new BaseXPath("/*/*[@code='13563275']");
1033             results = xpath.selectNodes(getContext(context));
1034             result = results.get(0);
1035                 assertValueOfXPath("http://c.moreover.com/click/here.pl?x13563273", result, "url");
1036             }
1037             }
1038 
1039     /* test other node types
1040     */
1041     public void testNodeTypes() throws JaxenException
1042     {
1043         Navigator nav = getNavigator();
1044         String url = "xml/contents.xml";
1045         log("Document [" + url + "]");
1046         Object document = nav.getDocument(url);
1047         XPath contextpath = new BaseXPath("/", nav);
1048         log("Initial Context :: " + contextpath);
1049         List list = contextpath.selectNodes(document);
1050         Iterator iter = list.iterator();
1051         while (iter.hasNext())
1052         {
1053             Object context = iter.next();
1054             assertCountXPath(3, context, "processing-instruction()");
1055             assertCountXPath(3, context, "/processing-instruction()");
1056             assertCountXPath(1, context, "/comment()");
1057             assertCountXPath(1, context, "comment()");
1058             assertCountXPath(2, context, "/child::node()/comment()");
1059             assertCountXPath(2, context, "/*/comment()");
1060             assertCountXPath(3, context, "//comment()");
1061         }
1062     }
1063 
1064     /* test positioning
1065     */
1066     public void testPositioning() throws JaxenException
1067     {
1068         Navigator nav = getNavigator();
1069         String url = "xml/fibo.xml";
1070         log("Document [" + url + "]");
1071         Object document = nav.getDocument(url);
1072         XPath contextpath = new BaseXPath("/", nav);
1073         log("Initial Context :: " + contextpath);
1074         List list = contextpath.selectNodes(document);
1075         Iterator iter = list.iterator();
1076         while (iter.hasNext())
1077         {
1078             Object context = iter.next();
1079             assertCountXPath(9, context, "/*/fibonacci[position() < 10]");
1080             assertValueOfXPath("196417", context, "sum(//fibonacci)");
1081             assertValueOfXPath("325", context, "sum(//fibonacci/@index)");
1082             assertValueOfXPath("1", context, "/*/fibonacci[2]");
1083             assertValueOfXPath("75025", context, "/*/fibonacci[ count(/*/fibonacci) ]");
1084             assertValueOfXPath("46368", context, "/*/fibonacci[ count(/*/fibonacci) - 1 ]");
1085         }
1086     }
1087 
1088     /* test number functions
1089     */
1090     /* test Axes 
1091     */
1092     public void testid54853() throws JaxenException
1093     {
1094         Navigator nav = getNavigator();
1095         String url = "xml/web.xml";
1096         log("Document [" + url + "]");
1097         Object document = nav.getDocument(url);
1098         XPath contextpath = new BaseXPath("/", nav);
1099         log("Initial Context :: " + contextpath);
1100         List list = contextpath.selectNodes(document);
1101         Iterator iter = list.iterator();
1102         while (iter.hasNext())
1103         {
1104             Object context = iter.next();
1105             assertCountXPath(19, context, "descendant-or-self::*");
1106             assertCountXPath(19, context, "descendant::*");
1107             assertCountXPath(19, context, "/descendant::*");
1108             assertCountXPath(19, context, "/descendant-or-self::*");
1109             assertCountXPath(2, context, "/descendant::servlet");
1110             assertCountXPath(2, context, "/descendant-or-self::servlet");
1111             assertCountXPath(2, context, "descendant-or-self::servlet");
1112             assertCountXPath(2, context, "descendant::servlet");
1113             assertCountXPath(2, context, "/*/servlet");
1114             assertValueOfXPath("2", context, "count(/*/servlet)");
1115             assertCountXPath(2, context, "//servlet");
1116             assertValueOfXPath("2", context, "count(//servlet)");
1117         }
1118     }
1119 
1120     public void testid54932() throws JaxenException
1121     {
1122         Navigator nav = getNavigator();
1123         String url = "xml/web.xml";
1124         log("Document [" + url + "]");
1125         Object document = nav.getDocument(url);
1126         XPath contextpath = new BaseXPath("/web-app", nav);
1127         log("Initial Context :: " + contextpath);
1128         List list = contextpath.selectNodes(document);
1129         Iterator iter = list.iterator();
1130         while (iter.hasNext())
1131         {
1132             Object context = iter.next();
1133             assertCountXPath(2, context, "/descendant::servlet");
1134             assertCountXPath(2, context, "/descendant-or-self::servlet");
1135             assertCountXPath(2, context, "descendant-or-self::servlet");
1136             assertCountXPath(2, context, "descendant::servlet");
1137         }
1138     }
1139 
1140     public void testCountFunction() throws JaxenException
1141     {
1142         Navigator nav = getNavigator();
1143         String url = "xml/much_ado.xml";
1144         log("Document [" + url + "]");
1145         Object document = nav.getDocument(url);
1146         XPath contextpath = new BaseXPath("/", nav);
1147         log("Initial Context :: " + contextpath);
1148         List list = contextpath.selectNodes(document);
1149         Iterator iter = list.iterator();
1150         while (iter.hasNext())
1151         {
1152             Object context = iter.next();
1153             assertCountXPath(5, context, "/descendant::ACT");
1154             assertCountXPath(5, context, "descendant::ACT");
1155             assertValueOfXPath("Much Ado about Nothing", context, "/PLAY/TITLE");
1156             assertValueOfXPath("4", context, "2+2");
1157             assertValueOfXPath("21", context, "5 * 4 + 1");
1158             assertValueOfXPath("5", context, "count(descendant::ACT)");
1159             assertValueOfXPath("35", context, "10 + count(descendant::ACT) * 5");
1160             assertValueOfXPath("75", context, "(10 + count(descendant::ACT)) * 5");
1161         }
1162     }
1163 
1164     public void testCountFunctionMore() throws JaxenException
1165     {
1166         Navigator nav = getNavigator();
1167         String url = "xml/much_ado.xml";
1168         log("Document [" + url + "]");
1169         Object document = nav.getDocument(url);
1170         XPath contextpath = new BaseXPath("/PLAY/ACT[2]/SCENE[1]", nav);
1171         log("Initial Context :: " + contextpath);
1172         List list = contextpath.selectNodes(document);
1173         Iterator iter = list.iterator();
1174         while (iter.hasNext())
1175         {
1176             Object context = iter.next();
1177             assertCountXPath(5, context, "/descendant::ACT");
1178             assertCountXPath(5, context, "../../descendant::ACT");
1179             assertCountXPath(141, context, "/PLAY/ACT[2]/SCENE[1]/descendant::SPEAKER");
1180             assertCountXPath(141, context, "descendant::SPEAKER");
1181             assertValueOfXPath("646", context, "count(descendant::*)+1");
1182             assertValueOfXPath("142", context, "count(descendant::SPEAKER)+1");
1183             assertValueOfXPath("2", context, "count(ancestor::*)");
1184             assertValueOfXPath("1", context, "count(ancestor::PLAY)");
1185             assertValueOfXPath("3", context, "count(ancestor-or-self::*)");
1186             assertValueOfXPath("1", context, "count(ancestor-or-self::PLAY)");
1187             assertValueOfXPath("6", context, "5+count(ancestor::*)-1");
1188         }
1189     }
1190 
1191     public void testCorrectPredicateApplication() throws JaxenException
1192     {
1193         Navigator nav = getNavigator();
1194         String url = "xml/much_ado.xml";
1195         log("Document [" + url + "]");
1196         Object document = nav.getDocument(url);
1197         XPath contextpath = new BaseXPath("/", nav);
1198         log("Initial Context :: " + contextpath);
1199         List list = contextpath.selectNodes(document);
1200         Iterator iter = list.iterator();
1201         while (iter.hasNext())
1202         {
1203             Object context = iter.next();
1204             /* Test correct predicate application
1205             */
1206             assertValueOfXPath("5", context, "count(/PLAY/ACT/SCENE[1])");
1207         }
1208     }
1209 
1210     /* test axis node ordering
1211     */
1212     public void testAxisNodeOrdering() throws JaxenException
1213     {
1214         Navigator nav = getNavigator();
1215         String url = "xml/web.xml";
1216         log("Document [" + url + "]");
1217         Object document = nav.getDocument(url);
1218         XPath contextpath = new BaseXPath("/", nav);
1219         log("Initial Context :: " + contextpath);
1220         List list = contextpath.selectNodes(document);
1221         Iterator iter = list.iterator();
1222         while (iter.hasNext())
1223         {
1224             Object context = iter.next();
1225             /* Reported as Jira issue JAXEN-24
1226             */
1227             assertCountXPath(1, context, "//servlet-mapping/preceding::*[1][name()='description']");
1228             assertCountXPath(1, context, "/web-app/servlet//description/following::*[1][name()='servlet-mapping']");
1229             assertCountXPath(1, context, "/web-app/servlet//description/following::*[2][name()='servlet-name']");
1230         }
1231     }
1232 
1233     /* test document function
1234     */
1235     public void testDocumentFunction1() throws JaxenException
1236     {
1237         Navigator nav = getNavigator();
1238         String url = "xml/text.xml";
1239         log("Document [" + url + "]");
1240         Object document = nav.getDocument(url);
1241         XPath contextpath = new BaseXPath("/", nav);
1242         log("Initial Context :: " + contextpath);
1243         List list = contextpath.selectNodes(document);
1244         Iterator iter = list.iterator();
1245         while (iter.hasNext())
1246         {
1247             Object context = iter.next();
1248                 Object result = assertCountXPath2(1, context, "document('xml/web.xml')");
1249                 assertValueOfXPath("snoop", result, "/web-app/servlet[1]/servlet-name");
1250                 assertValueOfXPath("snoop", result, "/web-app/servlet[1]/servlet-name/text()");
1251             assertValueOfXPath("snoop", context, "document('xml/web.xml')/web-app/servlet[1]/servlet-name");
1252         }
1253     }
1254 
1255     /* Test to check if the context changes when an extension function is used.
1256     First test is an example, second is the actual test.
1257     
1258     */
1259     public void testDocumentFunctionContextExample() throws JaxenException
1260     {
1261         Navigator nav = getNavigator();
1262         String url = "xml/text.xml";
1263         log("Document [" + url + "]");
1264         Object document = nav.getDocument(url);
1265         XPath contextpath = new BaseXPath("/foo/bar/cheese[1]", nav);
1266         log("Initial Context :: " + contextpath);
1267         List list = contextpath.selectNodes(document);
1268         Iterator iter = list.iterator();
1269         while (iter.hasNext())
1270         {
1271             Object context = iter.next();
1272             assertValueOfXPath("3foo3", context, "concat(./@id,'foo',@id)");
1273             assertValueOfXPath("3snoop3", context, "concat(./@id,document('xml/web.xml')/web-app/servlet[1]/servlet-name,./@id)");
1274         }
1275     }
1276 
1277     public void testDocumentFunctionActual() throws JaxenException
1278     {
1279         Navigator nav = getNavigator();
1280         String url = "xml/message.xml";
1281         log("Document [" + url + "]");
1282         Object document = nav.getDocument(url);
1283         XPath contextpath = new BaseXPath("/", nav);
1284         log("Initial Context :: " + contextpath);
1285         List list = contextpath.selectNodes(document);
1286         Iterator iter = list.iterator();
1287         while (iter.hasNext())
1288         {
1289             Object context = iter.next();
1290             assertValueOfXPath("Pruefgebiete", context, "/message/body/data/items/item[name/text()='parentinfo']/value");
1291             assertValueOfXPath("Pruefgebiete", context, "document('xml/message.xml')/message/body/data/items/item[name/text()='parentinfo']/value");
1292         }
1293     }
1294 
1295     /* test behaviour of AbsoluteLocationPath
1296     */
1297     public void testAbsoluteLocationPaths() throws JaxenException
1298     {
1299         Navigator nav = getNavigator();
1300         String url = "xml/simple.xml";
1301         log("Document [" + url + "]");
1302         Object document = nav.getDocument(url);
1303         XPath contextpath = new BaseXPath("/root/a", nav);
1304         log("Initial Context :: " + contextpath);
1305         List list = contextpath.selectNodes(document);
1306         Iterator iter = list.iterator();
1307         while (iter.hasNext())
1308         {
1309             Object context = iter.next();
1310             assertValueOfXPath("ab", context, "concat( ., /root/b )");
1311             assertValueOfXPath("ba", context, "concat( ../b, . )");
1312             assertValueOfXPath("ba", context, "concat( /root/b, . )");
1313             assertValueOfXPath("db", context, "concat( /root/c/d, ../b )");
1314         }
1315     }
1316 
1317     /* test the translate() function
1318     */
1319     public void testTranslateFunction() throws JaxenException
1320     {
1321         Navigator nav = getNavigator();
1322         String url = "xml/simple.xml";
1323         log("Document [" + url + "]");
1324         Object document = nav.getDocument(url);
1325         XPath contextpath = new BaseXPath("/", nav);
1326         log("Initial Context :: " + contextpath);
1327         List list = contextpath.selectNodes(document);
1328         Iterator iter = list.iterator();
1329         while (iter.hasNext())
1330         {
1331             Object context = iter.next();
1332             assertValueOfXPath("", context, "translate( '', '', '' )");
1333             assertValueOfXPath("abcd", context, "translate( 'abcd', '', '' )");
1334             assertValueOfXPath("abcd", context, "translate( 'abcd', 'abcd', 'abcd' )");
1335             assertValueOfXPath("abcd", context, "translate( 'abcd', 'dcba', 'dcba' )");
1336             assertValueOfXPath("dcba", context, "translate( 'abcd', 'abcd', 'dcba' )");
1337             assertValueOfXPath("ab", context, "translate( 'abcd', 'abcd', 'ab' )");
1338             assertValueOfXPath("cd", context, "translate( 'abcd', 'cdab', 'cd' )");
1339             assertValueOfXPath("xy", context, "translate( 'abcd', 'acbd', 'xy' )");
1340             assertValueOfXPath("abcd", context, "translate( 'abcd', 'abcdb', 'abcdb' )");
1341             assertValueOfXPath("abcd", context, "translate( 'abcd', 'abcd', 'abcdb' )");
1342         }
1343     }
1344 
1345     public void testSubstringFunction() throws JaxenException
1346     {
1347         Navigator nav = getNavigator();
1348         String url = "xml/simple.xml";
1349         log("Document [" + url + "]");
1350         Object document = nav.getDocument(url);
1351         XPath contextpath = new BaseXPath("/", nav);
1352         log("Initial Context :: " + contextpath);
1353         List list = contextpath.selectNodes(document);
1354         Iterator iter = list.iterator();
1355         while (iter.hasNext())
1356         {
1357             Object context = iter.next();
1358             assertValueOfXPath("234", context, "substring('12345', 1.5, 2.6)");
1359             assertValueOfXPath("12", context, "substring('12345', 0, 3)");
1360             assertValueOfXPath("", context, "substring('12345', 0 div 0, 3)");
1361             assertValueOfXPath("", context, "substring('12345', 1, 0 div 0)");
1362             assertValueOfXPath("12345", context, "substring('12345', -42, 1 div 0)");
1363             assertValueOfXPath("", context, "substring('12345', -1 div 0, 1 div 0)");
1364             assertValueOfXPath("345", context, "substring('12345', 3)");
1365             assertValueOfXPath("12345", context, "substring('12345',1,15)");
1366         }
1367     }
1368 
1369     /* Some tests for the normalize-space() function
1370     */
1371     public void testNormalizeSpaceFunction() throws JaxenException
1372     {
1373         Navigator nav = getNavigator();
1374         String url = "xml/simple.xml";
1375         log("Document [" + url + "]");
1376         Object document = nav.getDocument(url);
1377         XPath contextpath = new BaseXPath("/", nav);
1378         log("Initial Context :: " + contextpath);
1379         List list = contextpath.selectNodes(document);
1380         Iterator iter = list.iterator();
1381         while (iter.hasNext())
1382         {
1383             Object context = iter.next();
1384             assertValueOfXPath("abc", context, "normalize-space('    abc    ')");
1385             assertValueOfXPath("a b c", context, "normalize-space(' a  b  c  ')");
1386             assertValueOfXPath("a b c", context, "normalize-space(' a \n b \n  c')");
1387             /* Next test case addresses issue JAXEN-22
1388             */
1389             assertValueOfXPath("", context, "normalize-space(' ')");
1390             /* Next test case addresses issue JAXEN-29
1391             */
1392             assertValueOfXPath("", context, "normalize-space('')");
1393         }
1394     }
1395 
1396     /* test cases for String extension functions
1397     */
1398     public void testStringExtensionFunctions() throws JaxenException
1399     {
1400         Navigator nav = getNavigator();
1401         String url = "xml/web.xml";
1402         log("Document [" + url + "]");
1403         Object document = nav.getDocument(url);
1404         XPath contextpath = new BaseXPath("/web-app/servlet[1]", nav);
1405         log("Initial Context :: " + contextpath);
1406         List list = contextpath.selectNodes(document);
1407         Iterator iter = list.iterator();
1408         while (iter.hasNext())
1409         {
1410             Object context = iter.next();
1411             assertValueOfXPath("SNOOPSERVLET", context, "upper-case( servlet-class )");
1412             assertValueOfXPath("snoopservlet", context, "lower-case( servlet-class )");
1413             assertValueOfXPath("SNOOPSERVLET", context, "upper-case( servlet-class, 'fr' )");
1414             assertValueOfXPath("SNOOPSERVLET", context, "upper-case( servlet-class, 'fr-CA' )");
1415             assertValueOfXPath("SNOOPSERVLET", context, "upper-case( servlet-class, 'es-ES-Traditional_WIN' )");
1416             assertValueOfXPath("true", context, "ends-with( servlet-class, 'Servlet' )");
1417             assertValueOfXPath("false", context, "ends-with( servlet-class, 'S' )");
1418         }
1419     }
1420 
1421     /* test cases for the lang() function
1422     */
1423     public void testLangFunction() throws JaxenException
1424     {
1425         Navigator nav = getNavigator();
1426         String url = "xml/lang.xml";
1427         log("Document [" + url + "]");
1428         Object document = nav.getDocument(url);
1429         XPath contextpath = new BaseXPath("/", nav);
1430         log("Initial Context :: " + contextpath);
1431         List list = contextpath.selectNodes(document);
1432         Iterator iter = list.iterator();
1433         while (iter.hasNext())
1434         {
1435             Object context = iter.next();
1436             assertCountXPath(0, context, "/e1/e2[lang('hr')]");
1437             assertCountXPath(1, context, "/e1/e2/e3[lang('en')]");
1438             assertCountXPath(1, context, "/e1/e2/e3[lang('en-US')]");
1439             assertCountXPath(0, context, "/e1/e2/e3[lang('en-GB')]");
1440             assertCountXPath(2, context, "/e1/e2/e3[lang('hu')]");
1441             assertCountXPath(0, context, "/e1/e2/e3[lang('hu-HU')]");
1442             assertCountXPath(1, context, "/e1/e2/e3[lang('es')]");
1443             assertCountXPath(0, context, "/e1/e2/e3[lang('es-BR')]");
1444         }
1445     }
1446 
1447     /* test namespace
1448     */
1449     public void testNamespacesAgain() throws JaxenException
1450     {
1451         Navigator nav = getNavigator();
1452         String url = "xml/namespaces.xml";
1453         log("Document [" + url + "]");
1454         Object document = nav.getDocument(url);
1455         XPath contextpath = new BaseXPath("/", nav);
1456         log("Initial Context :: " + contextpath);
1457         List list = contextpath.selectNodes(document);
1458         SimpleNamespaceContext nsContext = new SimpleNamespaceContext();
1459         nsContext.addNamespace("alias", "http://fooNamespace/");
1460         nsContext.addNamespace("bar", "http://barNamespace/");
1461         nsContext.addNamespace("voo", "http://fooNamespace/");
1462         nsContext.addNamespace("foo", "http://fooNamespace/");
1463         getContextSupport().setNamespaceContext(nsContext);
1464         Iterator iter = list.iterator();
1465         while (iter.hasNext())
1466         {
1467             Object context = iter.next();
1468             assertCountXPath(1, context, "/*");
1469             assertCountXPath(1, context, "/foo:a");
1470             assertCountXPath(1, context, "/foo:a/b");
1471             assertCountXPath(1, context, "/voo:a/b/c");
1472             assertCountXPath(1, context, "/voo:a/bar:f");
1473             assertCountXPath(1, context, "/*[namespace-uri()='http://fooNamespace/' and local-name()='a']");
1474             assertCountXPath(1, context, "/*[local-name()='a' and namespace-uri()='http://fooNamespace/']/*[local-name()='x' and namespace-uri()='http://fooNamespace/']");
1475             assertCountXPath(1, context, "/*[local-name()='a' and namespace-uri()='http://fooNamespace/']/*[local-name()='x' and namespace-uri()='http://fooNamespace/']/*[local-name()='y' and namespace-uri()='http://fooNamespace/']");
1476         }
1477     }
1478 
1479     /* the prefix here and in the document have no relation; it's their
1480     namespace-uri binding that counts 
1481     */
1482     public void testPrefixDoesntMatter() throws JaxenException
1483     {
1484         Navigator nav = getNavigator();
1485         String url = "xml/namespaces.xml";
1486         log("Document [" + url + "]");
1487         Object document = nav.getDocument(url);
1488         XPath contextpath = new BaseXPath("/", nav);
1489         log("Initial Context :: " + contextpath);
1490         List list = contextpath.selectNodes(document);
1491         SimpleNamespaceContext nsContext = new SimpleNamespaceContext();
1492         nsContext.addNamespace("foo", "http://somethingElse/");
1493         getContextSupport().setNamespaceContext(nsContext);
1494         Iterator iter = list.iterator();
1495         while (iter.hasNext())
1496         {
1497             Object context = iter.next();
1498             assertCountXPath(0, context, "/foo:a/b/c");
1499         }
1500     }
1501 
1502     public void testNamespaces() throws JaxenException
1503     {
1504         Navigator nav = getNavigator();
1505         String url = "xml/namespaces.xml";
1506         log("Document [" + url + "]");
1507         Object document = nav.getDocument(url);
1508         XPath contextpath = new BaseXPath("/", nav);
1509         log("Initial Context :: " + contextpath);
1510         List list = contextpath.selectNodes(document);
1511         SimpleNamespaceContext nsContext = new SimpleNamespaceContext();
1512         nsContext.addNamespace("alias", "http://fooNamespace/");
1513         nsContext.addNamespace("bar", "http://barNamespace/");
1514         nsContext.addNamespace("foo", "http://fooNamespace/");
1515         getContextSupport().setNamespaceContext(nsContext);
1516         Iterator iter = list.iterator();
1517         while (iter.hasNext())
1518         {
1519             Object context = iter.next();
1520             assertValueOfXPath("Hello", context, "/foo:a/b/c");
1521             assertValueOfXPath("Hey", context, "/foo:a/foo:d/foo:e");
1522             assertValueOfXPath("Hey3", context, "/foo:a/alias:x/alias:y");
1523             assertValueOfXPath("Hey3", context, "/foo:a/foo:x/foo:y");
1524             assertValueOfXPath("Hey3", context, "/*[local-name()='a' and namespace-uri()='http://fooNamespace/']/*[local-name()='x' and namespace-uri()='http://fooNamespace/']/*[local-name()='y' and namespace-uri()='http://fooNamespace/']");
1525         }
1526     }
1527 
1528     public void testNoNamespace() throws JaxenException
1529     {
1530         Navigator nav = getNavigator();
1531         String url = "xml/defaultNamespace.xml";
1532         log("Document [" + url + "]");
1533         Object document = nav.getDocument(url);
1534         XPath contextpath = new BaseXPath("/", nav);
1535         log("Initial Context :: " + contextpath);
1536         List list = contextpath.selectNodes(document);
1537         Iterator iter = list.iterator();
1538         while (iter.hasNext())
1539         {
1540             Object context = iter.next();
1541             /* NOTE: /a/b/c selects elements in no namespace only!
1542             */
1543             assertCountXPath(0, context, "/a/b/c");
1544             /*
1545                 The following test uses an unbound prefix 'x' and should throw an exception.
1546                 Addresses issue JAXEN-18.
1547                 Turns out this isn't really tested as the test didn't fail when the exception wasn't thrown.
1548               <test select="/x:a/x:b/x:c" count="0" exception="true"/>
1549 
1550             */
1551         }
1552     }
1553 
1554     public void testNamespaceResolution() throws JaxenException
1555     {
1556         Navigator nav = getNavigator();
1557         String url = "xml/defaultNamespace.xml";
1558         log("Document [" + url + "]");
1559         Object document = nav.getDocument(url);
1560         XPath contextpath = new BaseXPath("/", nav);
1561         log("Initial Context :: " + contextpath);
1562         List list = contextpath.selectNodes(document);
1563         SimpleNamespaceContext nsContext = new SimpleNamespaceContext();
1564         nsContext.addNamespace("dummy", "http://dummyNamespace/");
1565         getContextSupport().setNamespaceContext(nsContext);
1566         Iterator iter = list.iterator();
1567         while (iter.hasNext())
1568         {
1569             Object context = iter.next();
1570             assertCountXPath(1, context, "/dummy:a/dummy:b/dummy:c");
1571         }
1572     }
1573 
1574     public void testTextNodes() throws JaxenException
1575     {
1576         Navigator nav = getNavigator();
1577         String url = "xml/text.xml";
1578         log("Document [" + url + "]");
1579         Object document = nav.getDocument(url);
1580         XPath contextpath = new BaseXPath("/", nav);
1581         log("Initial Context :: " + contextpath);
1582         List list = contextpath.selectNodes(document);
1583         Iterator iter = list.iterator();
1584         while (iter.hasNext())
1585         {
1586             Object context = iter.next();
1587             assertCountXPath(3, context, "/foo/bar/text()");
1588             assertValueOfXPath("baz", context, "normalize-space(/foo/bar/text())");
1589         }
1590     }
1591 
1592     public void testNamespaceNodeCounts1() throws JaxenException
1593     {
1594         Navigator nav = getNavigator();
1595         String url = "xml/testNamespaces.xml";
1596         log("Document [" + url + "]");
1597         Object document = nav.getDocument(url);
1598         XPath contextpath = new BaseXPath("/", nav);
1599         log("Initial Context :: " + contextpath);
1600         List list = contextpath.selectNodes(document);
1601         Iterator iter = list.iterator();
1602         while (iter.hasNext())
1603         {
1604             Object context = iter.next();
1605             /* the root is not an element, so no namespaces
1606             */
1607             assertCountXPath(0, context, "namespace::*");
1608             assertCountXPath(0, context, "/namespace::*");
1609             /* must count the default xml: prefix as well
1610             */
1611             assertCountXPath(3, context, "/Template/Application1/namespace::*");
1612             assertCountXPath(3, context, "/Template/Application2/namespace::*");
1613             /* every element has separate copies
1614             */
1615             assertCountXPath(25, context, "//namespace::*");
1616         }
1617     }
1618 
1619     public void testNamespaceNodeCounts() throws JaxenException
1620     {
1621         Navigator nav = getNavigator();
1622         String url = "xml/testNamespaces.xml";
1623         log("Document [" + url + "]");
1624         Object document = nav.getDocument(url);
1625         XPath contextpath = new BaseXPath("/Template/Application1", nav);
1626         log("Initial Context :: " + contextpath);
1627         List list = contextpath.selectNodes(document);
1628         Iterator iter = list.iterator();
1629         while (iter.hasNext())
1630         {
1631             Object context = iter.next();
1632             /* must count the default xml: prefix as well
1633             */
1634             assertCountXPath(3, context, "namespace::*");
1635             assertCountXPath(0, context, "/namespace::*");
1636             assertCountXPath(3, context, "/Template/Application1/namespace::*");
1637             assertCountXPath(3, context, "/Template/Application2/namespace::*");
1638             assertCountXPath(25, context, "//namespace::*");
1639             assertCountXPath(8, context, "//namespace::xplt");
1640             /* the name test literally matches the prefix as given in the
1641               document, and does not use the uri
1642             */
1643             assertCountXPath(0, context, "//namespace::somethingelse");
1644         }
1645     }
1646 
1647     public void testNamespaceNodesHaveParent() throws JaxenException
1648     {
1649         Navigator nav = getNavigator();
1650         String url = "xml/testNamespaces.xml";
1651         log("Document [" + url + "]");
1652         Object document = nav.getDocument(url);
1653         XPath contextpath = new BaseXPath("/", nav);
1654         log("Initial Context :: " + contextpath);
1655         List list = contextpath.selectNodes(document);
1656         Iterator iter = list.iterator();
1657         while (iter.hasNext())
1658         {
1659             Object context = iter.next();
1660             /* namespace nodes have their element as their parent
1661             */
1662             assertCountXPath(1, context, "/Template/namespace::xml/parent::Template");
1663         }
1664     }
1665 
1666     /* namespace nodes can also be used as context nodes
1667     */
1668     public void testNamespaceNodeAsContext() throws JaxenException
1669     {
1670         Navigator nav = getNavigator();
1671         String url = "xml/testNamespaces.xml";
1672         log("Document [" + url + "]");
1673         Object document = nav.getDocument(url);
1674         XPath contextpath = new BaseXPath("/Template/namespace::xml", nav);
1675         log("Initial Context :: " + contextpath);
1676         List list = contextpath.selectNodes(document);
1677         Iterator iter = list.iterator();
1678         while (iter.hasNext())
1679         {
1680             Object context = iter.next();
1681             assertCountXPath(1, context, "parent::Template");
1682         }
1683     }
1684 }