1   /*
2    * $Header$
3    * $Revision$
4    * $Date$
5    *
6    * ====================================================================
7    *
8    * Copyright 2000-2003 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 are
13   * met:
14   * 
15   *   * Redistributions of source code must retain the above copyright
16   *     notice, this list of conditions and the following disclaimer.
17   * 
18   *   * Redistributions in binary form must reproduce the above copyright
19   *     notice, this list of conditions and the following disclaimer in the
20   *     documentation and/or other materials provided with the distribution.
21   * 
22   *   * Neither the name of the Jaxen Project nor the names of its
23   *     contributors may be used to endorse or promote products derived 
24   *     from this software without specific prior written permission.
25   * 
26   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
27   * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28   * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
29   * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
30   * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31   * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32   * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33   * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34   * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35   * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37   *
38   * ====================================================================
39   * This software consists of voluntary contributions made by many 
40   * individuals on behalf of the Jaxen Project and was originally 
41   * created by bob mcwhirter <bob@werken.com> and 
42   * James Strachan <jstrachan@apache.org>.  For more information on the 
43   * Jaxen Project, please see <http://www.jaxen.org/>.
44   * 
45   * $Id$
46   */
47  
48  
49  package org.jaxen.test;
50  
51  import junit.framework.TestCase;
52  
53  import javax.xml.parsers.DocumentBuilder;
54  import javax.xml.parsers.DocumentBuilderFactory;
55  import javax.xml.parsers.ParserConfigurationException;
56  
57  import java.io.IOException;
58  import java.util.Iterator;
59  import java.util.List;
60  
61  import org.jaxen.JaxenException;
62  import org.jaxen.XPath;
63  import org.jaxen.dom.DOMXPath;
64  import org.w3c.dom.Document;
65  import org.w3c.dom.Element;
66  import org.w3c.dom.Node;
67  import org.xml.sax.SAXException;
68  
69  public class DOMXPathTest extends TestCase
70  {
71  
72      private static final String BASIC_XML = "xml/basic.xml";
73      private Document doc;
74      private DocumentBuilderFactory factory;
75  
76      public DOMXPathTest(String name)
77      {
78          super( name );
79      }
80      
81      public void setUp() throws ParserConfigurationException {
82          factory = DocumentBuilderFactory.newInstance();
83          factory.setNamespaceAware(true);
84          doc = factory.newDocumentBuilder().newDocument();        
85      }
86      
87  
88      public void testConstruction() throws JaxenException
89      {
90          DOMXPath xpath = new DOMXPath( "/foo/bar/baz" );
91          assertEquals("/foo/bar/baz", xpath.toString());
92      }
93      
94      public void testConstructionWithNamespacePrefix() throws JaxenException
95      {
96          DOMXPath xpath = new DOMXPath( "/p:foo/p:bar/a:baz" );
97          assertEquals("/p:foo/p:bar/a:baz", xpath.toString());
98      }
99      
100     public void testNamespaceDeclarationsAreNotAttributes() 
101       throws JaxenException {
102         
103         Element root = doc.createElementNS("http://www.example.org/", "root");
104         doc.appendChild(root);
105         root.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", "http://www.example.org/");
106         
107         DOMXPath xpath = new DOMXPath( "count(/*/@*)" );
108         
109         Number value = xpath.numberValueOf(doc);
110         assertEquals(0, value.intValue());
111         
112     }
113 
114     
115     // see JAXEN-105
116     public void testConsistentNamespaceDeclarations() 
117       throws JaxenException {
118         
119         Element root = doc.createElement("root");
120         doc.appendChild(root);
121         Element child = doc.createElementNS("http://www.example.org", "foo:child");
122         root.appendChild(child);
123         // different prefix
124         child.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:foo2", "http://www.contradictory.org");
125         
126         XPath xpath = new DOMXPath("//namespace::node()");
127         List result = xpath.selectNodes(doc);
128         assertEquals(4, result.size());
129         
130     }
131 
132     // see JAXEN-105
133     public void testInconsistentNamespaceDeclarations() 
134       throws JaxenException {
135         
136         Element root = doc.createElement("root");
137         doc.appendChild(root);
138         Element child = doc.createElementNS("http://www.example.org", "foo:child");
139         root.appendChild(child);
140         // same prefix
141         child.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:foo", "http://www.contradictory.org");
142         
143         XPath xpath = new DOMXPath("//namespace::node()");
144         List result = xpath.selectNodes(doc);
145         assertEquals(3, result.size());
146         
147     }
148 
149     // see JAXEN-105
150     public void testIntrinsicNamespaceDeclarationOfElementBeatsContradictoryXmlnsPreAttr() 
151       throws JaxenException {
152         
153         Element root = doc.createElement("root");
154         doc.appendChild(root);
155         Element child = doc.createElementNS("http://www.example.org", "foo:child");
156         root.appendChild(child);
157         // same prefix
158         child.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:foo", "http://www.contradictory.org");
159         
160         XPath xpath = new DOMXPath("//namespace::node()[name(.)='foo']");
161         List result = xpath.selectNodes(doc);
162         assertEquals(1, result.size());
163         Node node = (Node) result.get(0);
164         assertEquals("http://www.example.org", node.getNodeValue());
165         
166     }    
167     
168     // see JAXEN-105
169     public void testIntrinsicNamespaceDeclarationOfAttrBeatsContradictoryXmlnsPreAttr() 
170       throws JaxenException {
171         
172         Element root = doc.createElement("root");
173         doc.appendChild(root);
174         root.setAttributeNS("http://www.example.org/", "foo:a", "value");
175         // same prefix, different namespace
176         root.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:foo", "http://www.contradictory.org");
177         
178         XPath xpath = new DOMXPath("//namespace::node()[name(.)='foo']");
179         List result = xpath.selectNodes(doc);
180         assertEquals(1, result.size());
181         Node node = (Node) result.get(0);
182         assertEquals("http://www.example.org/", node.getNodeValue());
183         
184     }    
185     
186     // see JAXEN-105
187     public void testIntrinsicNamespaceDeclarationOfElementBeatsContradictoryIntrinsicNamespaceOfAttr() 
188       throws JaxenException {
189         
190         Element root = doc.createElementNS("http://www.example.org", "pre:root");
191         doc.appendChild(root);
192         // same prefix
193         root.setAttributeNS("http://www.contradictory.org", "pre:foo", "value");
194         
195         XPath xpath = new DOMXPath("//namespace::node()[name(.)='pre']");
196         List result = xpath.selectNodes(doc);
197         assertEquals(1, result.size());
198         Node node = (Node) result.get(0);
199         assertEquals("http://www.example.org", node.getNodeValue());
200         
201     }    
202     
203     // Jaxen-54
204     public void testUpdateDOMNodesReturnedBySelectNodes() 
205       throws JaxenException {
206         
207         Element root = doc.createElementNS("http://www.example.org/", "root");
208         doc.appendChild(root);
209         root.appendChild(doc.createComment("data"));
210         
211         DOMXPath xpath = new DOMXPath( "//comment()" );
212         
213         List results = xpath.selectNodes(doc);
214         Node backroot = (Node) results.get(0);
215         backroot.setNodeValue("test");
216         assertEquals("test", backroot.getNodeValue());
217         
218     }
219 
220     public void testSelection() 
221       throws JaxenException, ParserConfigurationException, SAXException, IOException {
222         XPath xpath = new DOMXPath( "/foo/bar/baz" );
223 
224         DocumentBuilder builder = factory.newDocumentBuilder();
225     
226         Document document = builder.parse( BASIC_XML );
227 
228         List results = xpath.selectNodes( document );
229 
230         assertEquals( 3,
231                       results.size() );
232 
233         Iterator iter = results.iterator();
234 
235         assertEquals( "baz",
236                       ((Element)iter.next()).getLocalName() );
237 
238         assertEquals( "baz",
239                       ((Element)iter.next()).getLocalName() );
240 
241         assertEquals( "baz",
242                       ((Element)iter.next()).getLocalName() );
243 
244         assertTrue( ! iter.hasNext() );
245 
246     }
247     
248     // Jaxen-22
249     public void testPrecedingAxisWithPositionalPredicate() 
250       throws JaxenException, ParserConfigurationException, SAXException, IOException {
251         
252         XPath xpath = new DOMXPath( "//c/preceding::*[1][name()='d']" );
253         DocumentBuilder builder = factory.newDocumentBuilder();
254     
255         Document document = builder.parse( "xml/web2.xml" );
256         List result = xpath.selectNodes(document);
257         assertEquals(1, result.size());
258         
259     }
260     
261      
262     // Jaxen-22
263     public void testJaxen22() 
264       throws JaxenException, ParserConfigurationException, SAXException, IOException {
265         
266         XPath xpath = new DOMXPath( "name(//c/preceding::*[1])" );
267         DocumentBuilder builder = factory.newDocumentBuilder();
268     
269         doc = builder.parse("xml/web2.xml");
270         Object result = xpath.evaluate(doc);
271         assertEquals("d", result);
272     }
273     
274      
275     public void testPrecedingAxisInDocumentOrder() 
276       throws JaxenException {
277         
278         XPath xpath = new DOMXPath( "preceding::*" );
279     
280         Element root = doc.createElement("root");
281         doc.appendChild(root);
282         
283         Element a = doc.createElement("a");
284         root.appendChild(a);
285         Element b = doc.createElement("b");
286         root.appendChild(b);
287         Element c = doc.createElement("c");
288         a.appendChild(c);
289         
290         List result = xpath.selectNodes(b);
291         assertEquals(2, result.size());
292         assertEquals(a, result.get(0));
293         assertEquals(c, result.get(1));
294     }
295     
296      
297 }