14c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson/* 24c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Licensed to the Apache Software Foundation (ASF) under one 34c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * or more contributor license agreements. See the NOTICE file 44c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * distributed with this work for additional information 54c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * regarding copyright ownership. The ASF licenses this file 64c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * to you under the Apache License, Version 2.0 (the "License"); 74c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * you may not use this file except in compliance with the License. 84c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * You may obtain a copy of the License at 94c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Unless required by applicable law or agreed to in writing, software 134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * See the License for the specific language governing permissions and 164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * limitations under the License. 174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson/* 194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * $Id: XPathAPI.java 524807 2007-04-02 15:51:43Z zongaro $ 204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonpackage org.apache.xpath; 224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport javax.xml.transform.TransformerException; 244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xml.utils.PrefixResolver; 264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xml.utils.PrefixResolverDefault; 274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.objects.XObject; 284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.w3c.dom.Document; 304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.w3c.dom.Node; 314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.w3c.dom.NodeList; 324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.w3c.dom.traversal.NodeIterator; 334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson/** 354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * The methods in this class are convenience methods into the 364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * low-level XPath API. 374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * These functions tend to be a little slow, since a number of objects must be 384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * created for each evaluation. A faster way is to precompile the 394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * XPaths using the low-level API, and then just use the XPaths 404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * over and over. 414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * NOTE: In particular, each call to this method will create a new 434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * XPathContext, a new DTMManager... and thus a new DTM. That's very 444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * safe, since it guarantees that you're always processing against a 454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * fully up-to-date view of your document. But it's also portentially 464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * very expensive, since you're rebuilding the DTM every time. You should 474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * consider using an instance of CachedXPathAPI rather than these static 484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * methods. 494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see <a href="http://www.w3.org/TR/xpath">XPath Specification</a> 514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * */ 524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonpublic class XPathAPI 534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson{ 544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Use an XPath string to select a single node. XPath namespace 574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * prefixes are resolved from the context node, which may not 584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * be what you want (see the next method). 594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param contextNode The node to start searching from. 614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param str A valid XPath string. 624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return The first node found that matches the XPath, or null. 634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws TransformerException 654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public static Node selectSingleNode(Node contextNode, String str) 674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throws TransformerException 684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return selectSingleNode(contextNode, str, contextNode); 704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Use an XPath string to select a single node. 744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * XPath namespace prefixes are resolved from the namespaceNode. 754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param contextNode The node to start searching from. 774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param str A valid XPath string. 784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param namespaceNode The node from which prefixes in the XPath will be resolved to namespaces. 794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return The first node found that matches the XPath, or null. 804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws TransformerException 824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public static Node selectSingleNode( 844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson Node contextNode, String str, Node namespaceNode) 854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throws TransformerException 864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Have the XObject return its result as a NodeSetDTM. 894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson NodeIterator nl = selectNodeIterator(contextNode, str, namespaceNode); 904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Return the first node, or null 924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return nl.nextNode(); 934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Use an XPath string to select a nodelist. 974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * XPath namespace prefixes are resolved from the contextNode. 984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param contextNode The node to start searching from. 1004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param str A valid XPath string. 1014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return A NodeIterator, should never be null. 1024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws TransformerException 1044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public static NodeIterator selectNodeIterator(Node contextNode, String str) 1064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throws TransformerException 1074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return selectNodeIterator(contextNode, str, contextNode); 1094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Use an XPath string to select a nodelist. 1134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * XPath namespace prefixes are resolved from the namespaceNode. 1144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param contextNode The node to start searching from. 1164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param str A valid XPath string. 1174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param namespaceNode The node from which prefixes in the XPath will be resolved to namespaces. 1184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return A NodeIterator, should never be null. 1194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws TransformerException 1214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public static NodeIterator selectNodeIterator( 1234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson Node contextNode, String str, Node namespaceNode) 1244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throws TransformerException 1254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Execute the XPath, and have it return the result 1284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XObject list = eval(contextNode, str, namespaceNode); 1294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Have the XObject return its result as a NodeSetDTM. 1314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return list.nodeset(); 1324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Use an XPath string to select a nodelist. 1364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * XPath namespace prefixes are resolved from the contextNode. 1374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param contextNode The node to start searching from. 1394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param str A valid XPath string. 1404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return A NodeIterator, should never be null. 1414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws TransformerException 1434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public static NodeList selectNodeList(Node contextNode, String str) 1454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throws TransformerException 1464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return selectNodeList(contextNode, str, contextNode); 1484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Use an XPath string to select a nodelist. 1524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * XPath namespace prefixes are resolved from the namespaceNode. 1534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param contextNode The node to start searching from. 1554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param str A valid XPath string. 1564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param namespaceNode The node from which prefixes in the XPath will be resolved to namespaces. 1574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return A NodeIterator, should never be null. 1584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws TransformerException 1604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public static NodeList selectNodeList( 1624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson Node contextNode, String str, Node namespaceNode) 1634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throws TransformerException 1644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Execute the XPath, and have it return the result 1674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XObject list = eval(contextNode, str, namespaceNode); 1684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Return a NodeList. 1704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return list.nodelist(); 1714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Evaluate XPath string to an XObject. Using this method, 1754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * XPath namespace prefixes will be resolved from the namespaceNode. 1764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param contextNode The node to start searching from. 1774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param str A valid XPath string. 1784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return An XObject, which can be used to obtain a string, number, nodelist, etc, should never be null. 1794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see org.apache.xpath.objects.XObject 1804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see org.apache.xpath.objects.XNull 1814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see org.apache.xpath.objects.XBoolean 1824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see org.apache.xpath.objects.XNumber 1834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see org.apache.xpath.objects.XString 1844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see org.apache.xpath.objects.XRTreeFrag 1854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws TransformerException 1874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public static XObject eval(Node contextNode, String str) 1894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throws TransformerException 1904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return eval(contextNode, str, contextNode); 1924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Evaluate XPath string to an XObject. 1964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * XPath namespace prefixes are resolved from the namespaceNode. 1974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * The implementation of this is a little slow, since it creates 1984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * a number of objects each time it is called. This could be optimized 1994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * to keep the same objects around, but then thread-safety issues would arise. 2004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 2014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param contextNode The node to start searching from. 2024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param str A valid XPath string. 2034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param namespaceNode The node from which prefixes in the XPath will be resolved to namespaces. 2044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return An XObject, which can be used to obtain a string, number, nodelist, etc, should never be null. 2054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see org.apache.xpath.objects.XObject 2064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see org.apache.xpath.objects.XNull 2074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see org.apache.xpath.objects.XBoolean 2084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see org.apache.xpath.objects.XNumber 2094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see org.apache.xpath.objects.XString 2104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see org.apache.xpath.objects.XRTreeFrag 2114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 2124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws TransformerException 2134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 2144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public static XObject eval(Node contextNode, String str, Node namespaceNode) 2154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throws TransformerException 2164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Since we don't have a XML Parser involved here, install some default support 2194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // for things like namespaces, etc. 2204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // (Changed from: XPathContext xpathSupport = new XPathContext(); 2214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // because XPathContext is weak in a number of areas... perhaps 2224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // XPathContext should be done away with.) 2234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Create an XPathContext that doesn't support pushing and popping of 2244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // variable resolution scopes. Sufficient for simple XPath 1.0 expressions. 2254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XPathContext xpathSupport = new XPathContext(false); 2264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Create an object to resolve namespace prefixes. 2284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // XPath namespaces are resolved from the input context node's document element 2294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // if it is a root node, or else the current context node (for lack of a better 2304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // resolution space, given the simplicity of this sample code). 2314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson PrefixResolverDefault prefixResolver = new PrefixResolverDefault( 2324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson (namespaceNode.getNodeType() == Node.DOCUMENT_NODE) 2334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson ? ((Document) namespaceNode).getDocumentElement() : namespaceNode); 2344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Create the XPath object. 2364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XPath xpath = new XPath(str, null, prefixResolver, XPath.SELECT, null); 2374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Execute the XPath, and have it return the result 2394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // return xpath.execute(xpathSupport, contextNode, prefixResolver); 2404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int ctxtNode = xpathSupport.getDTMHandleFromNode(contextNode); 2414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return xpath.execute(xpathSupport, ctxtNode, prefixResolver); 2434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 2464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Evaluate XPath string to an XObject. 2474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * XPath namespace prefixes are resolved from the namespaceNode. 2484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * The implementation of this is a little slow, since it creates 2494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * a number of objects each time it is called. This could be optimized 2504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * to keep the same objects around, but then thread-safety issues would arise. 2514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 2524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param contextNode The node to start searching from. 2534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param str A valid XPath string. 2544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param prefixResolver Will be called if the parser encounters namespace 2554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * prefixes, to resolve the prefixes to URLs. 2564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return An XObject, which can be used to obtain a string, number, nodelist, etc, should never be null. 2574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see org.apache.xpath.objects.XObject 2584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see org.apache.xpath.objects.XNull 2594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see org.apache.xpath.objects.XBoolean 2604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see org.apache.xpath.objects.XNumber 2614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see org.apache.xpath.objects.XString 2624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see org.apache.xpath.objects.XRTreeFrag 2634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 2644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws TransformerException 2654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 2664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public static XObject eval( 2674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson Node contextNode, String str, PrefixResolver prefixResolver) 2684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throws TransformerException 2694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Since we don't have a XML Parser involved here, install some default support 2724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // for things like namespaces, etc. 2734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // (Changed from: XPathContext xpathSupport = new XPathContext(); 2744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // because XPathContext is weak in a number of areas... perhaps 2754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // XPathContext should be done away with.) 2764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Create the XPath object. 2774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XPath xpath = new XPath(str, null, prefixResolver, XPath.SELECT, null); 2784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Create an XPathContext that doesn't support pushing and popping of 2804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // variable resolution scopes. Sufficient for simple XPath 1.0 expressions. 2814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XPathContext xpathSupport = new XPathContext(false); 2824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Execute the XPath, and have it return the result 2844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int ctxtNode = xpathSupport.getDTMHandleFromNode(contextNode); 2854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return xpath.execute(xpathSupport, ctxtNode, prefixResolver); 2874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson} 289