<?xml version="1.0" standalone="no"?>
<!DOCTYPE s1 SYSTEM "../../style/dtd/document.dtd">
<!--
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
-->
 
<s1 title="Using the JAXP XPath APIs">
  <ul>
  <li><link anchor="basic">Basic steps</link></li>
  <li><link anchor="plugin">Plugging in the XPathFactory</link></li>
  <li><link anchor="namespacecontext">Using NamespaceContext</link></li>
  <li><link anchor="variableresolver">Using XPathVariableResolver</link></li>
  <li><link anchor="functionresolver">Using XPathFunctionResolver</link></li>
  <li><link anchor="sampleresolver">Using the sample XPathFunctionResolver</link></li>
  </ul>
  
  <anchor name="basic"/>
  <s2 title="Basic steps">
    <ol>
    <li><link anchor="xpathfactory">Instantiate an XPathFactory</link></li>
    <li><link anchor="xpath">Create an XPath</link></li>
    <li><link anchor="xpathexpression">(optional) Create an XPathExpression</link></li>
    <li><link anchor="evaluation">Evaluate the XPath expression in a specified context</link></li>
    </ol>
  <p>The following example illustrates the basic steps involved in evaluating an XPath expression.</p>
  <source>// 1. Instantiate an XPathFactory.
  javax.xml.xpath.XPathFactory factory = 
                    javax.xml.xpath.XPathFactory.newInstance();
  
  // 2. Use the XPathFactory to create a new XPath object
  javax.xml.xpath.XPath xpath = factory.newXPath();
  
  // 3. Compile an XPath string into an XPathExpression
  javax.xml.xpath.XPathExpression expression = xpath.compile("/doc/name");
  
  // 4. Evaluate the XPath expression on an input document
 String result = expression.evaluate(new org.xml.sax.InputSource("foo.xml"));
  </source>
  </s2>
  
  <anchor name="xpathfactory"/>
  <s2 title="1. Instantiate an XPathFactory">  
  <p><jump href="apidocs/javax/xml/xpath/XPathFactory.html">XPathFactory</jump> is an abstract class with two static 
  newInstance() methods (<jump href="apidocs/javax/xml/xpath/XPathFactory.html#newInstance()">newInstance()</jump> and
  <jump href="apidocs/javax/xml/xpath/XPathFactory.html#newInstance(java.lang.String)">newInstance(String uri)</jump>)
  that instantiate the concrete subclass designated as the javax.xml.xpath.XPathFactory service provider.
  The optional parameter uri specifies the object model. The implementation in &xslt4j2; only supports the
  W3C DOM object model, identified by the URI <jump href="apidocs/javax/xml/xpath/XPathFactory.html#DEFAULT_OBJECT_MODEL_URI">
  DEFAULT_OBJECT_MODEL_URI</jump>.</p>

  <p>The default service provider for the javax.xml.xpath.XPathFactory service is 
  <jump href="apidocs/org/apache/xpath/jaxp/XPathFactoryImpl.html">org.apache.xpath.jaxp.XPathFactoryImpl</jump>.
  </p>
  </s2>
  
  <anchor name="xpath"/>
  <s2 title="2. Create an XPath">
  You can use the <jump href="apidocs/javax/xml/xpath/XPathFactory.html#newXPath()">XPathFactory.newXPath()</jump> 
  method to create a new <jump href="apidocs/javax/xml/xpath/XPath.html">XPath</jump>.
  </s2>
  
  <anchor name="xpathexpression"/>
  <s2 title="3. (optional) Create an XPathExpression">
  You can use the <jump href="apidocs/javax/xml/xpath/XPath.html#compile(java.lang.String)">XPath.compile(String expression)</jump>
  method to compile an XPath string into an <jump href="apidocs/javax/xml/xpath/XPathExpression.html">XPathExpression</jump> object 
  for later evaluation. This is an optional step.
  You can evaluate an XPath expression without compiling it first. 
  </s2>

  <anchor name="evaluation"/>
  <s2 title="4. Evaluate an XPath expression">
  <p>If you compile an XPath String into an <jump href="apidocs/javax/xml/xpath/XPathExpression.html">XPathExpression</jump> 
  in step 3, you can use one of the four evaluate() methods in
  the XPathExpression interface to evaluate the XPath expression. If the evaluation context is a W3C Node in an 
  existing Document, you can use the <jump href="apidocs/javax/xml/xpath/XPathExpression.html#evaluate(java.lang.Object)">
  evaluate(Object item)</jump> or <jump href="apidocs/javax/xml/xpath/XPathExpression.html#evaluate(java.lang.Object, javax.xml.namespace.QName)">
  evaluate(Object item, QName returnType)</jump> method by passing the context item as the first parameter.
  The method with a returnType parameter allows you to specify the return type as one of the following supported 
  return types:
  <li><jump href="apidocs/javax/xml/xpath/XPathConstants.html#BOOLEAN">XPathConstants.BOOLEAN</jump></li>
  <li><jump href="apidocs/javax/xml/xpath/XPathConstants.html#NUMBER">XPathConstants.NUMBER</jump></li>
  <li><jump href="apidocs/javax/xml/xpath/XPathConstants.html#STRING">XPathConstants.STRING</jump></li>
  <li><jump href="apidocs/javax/xml/xpath/XPathConstants.html#NODESET">XPathConstants.NODESET</jump></li>
  <li><jump href="apidocs/javax/xml/xpath/XPathConstants.html#NODE">XPathConstants.NODE</jump></li>
  </p>
  <p>If the returnType parameter is not specified, the default is XPathConstants.STRING.</p>
  <p>If the evaluation context is an input document, you can use one of the two evaluate() methods with an 
  InputSource parameter (<jump href="apidocs/javax/xml/xpath/XPathExpression.html#evaluate(org.xml.sax.InputSource)">evaluate(InputSource source)</jump> 
  or <jump href="apidocs/javax/xml/xpath/XPathExpression.html#evaluate(org.xml.sax.InputSource, javax.xml.namespace.QName)">
  evaluate(InputSource source, QName returnType)</jump>) to evaluate the XPath expression.</p>
  <p>The compiling step allows you to reuse an XPath expression for evaluation on multiple contexts. 
  If an XPath expression is only used once, you can use one of the four evaluate() methods in the 
  <jump href="apidocs/javax/xml/xpath/XPath.html">XPath</jump> interface 
  to evaluate the XPath expression without compiling it first.</p>
  </s2>
  
  <anchor name="plugin"/>
  <s2 title="Plugging in the XPathFactory">
  <p>The Java API for XML Processing interfaces enable you to plug in your own implementation of XPathFactory.
  The abstract class XPathFactory has a static newInstance() method that instantiates a concrete Factory 
  which wraps the underlying implementation. The newInstance() method uses system property settings to determine 
  which implementation to instantiate.</p>
  <p>&xslt4j2; is distributed with a pre-configured setting for the provider of the XPathFactory service. This setting is in 
  xalan.jar in META-INF/services/javax.xml.xpath.XPathFactory, with a value of org.apache.xpath.jaxp.XPathFactoryImpl.</p>
  <p>You can plug in a new XPathFactory as follows (in order of precedence):
  <ol>
  <li>Set the system property "javax.xml.xpath.XPathFactory" + ":uri" from the command line when you 
  launch Java or from within your application, where uri is the URI of the underlying object model. The URI of
  the default W3C DOM object model is <code>http://java.sun.com/jaxp/xpath/dom</code>.</li>
  <li>Set the property in jaxp.properties in the JAVA_HOME/lib directory, where JAVA_HOME is the root of 
  the JDK.</li>
  <li>Revise the entry in src/META-INF/services/javax.xml.xpath.XPathFactory and rebuild xalan.jar. Each potential service 
  provider entry in this file is required to implement the method <code>isObjectModelSupported(String objectModel).</code>
  The first service provider found in class loader order that supports the specified object model will be used.</li>
  </ol>
  </p>
  </s2>
  
  <anchor name="namespacecontext"/>
  <s2 title="Using NamespaceContext">
  <p>If namespace prefixes are used in an XPath expression, the XPath processor needs to know what namespace URIs 
  the prefixes are bound to. Logically a prefix can only be bound to a single Namespace URI in the current scope. However,
  a Namespace URI can be bound to multiple prefixes in the current scope. The information about namespace 
  prefix to URI mappings is provided by an object that implements the 
  <jump href="apidocs/javax/xml/namespace/NamespaceContext.html">javax.xml.namespace.NamespaceContext</jump> interface.</p>
  <p>Suppose you want to evaluate the XPath expression <code>"/foo:document/bar:element"</code> on the following xml document:</p>
  <source>
  &lt;?xml version='1.0'?&gt;
  &lt;foo:document xmlns:foo="http://apache.org/foo" xmlns:bar="http://apache.org/bar"&gt;
    &lt;bar:element&gt;MyBar&lt;/bar:element&gt;
  &lt;/foo:document&gt;
  </source>
  
  <p>You need to create your own implementation of <jump href="apidocs/javax/xml/namespace/NamespaceContext.html">NamespaceContext</jump>
  to inform the XPath processor what namespace URIs
  the prefixes are bound to. For the example above, you can create a NamespaceContext implementation as follows:</p>
  <source>
    public class MyNamespaceContext implements NamespaceContext
    {
        public String getNamespaceURI(String prefix)
        {
            if (prefix.equals("foo"))
                return "http://apache.org/foo";
            else if (prefix.equals("bar"))
                return "http://apache.org/bar";
            else
                return XMLConstants.NULL_NS_URI;
        }
        
        public String getPrefix(String namespace)
        {
            if (namespace.equals("http://apache.org/foo"))
                return "foo";
            else if (namespace.equals("http://apache.org/bar"))
                return "bar";
            else
                return null;
        }

        public Iterator getPrefixes(String namespace)
        {
            return null;
        }
    }  
  </source>
  
  <p>Then you can use the <jump href="apidocs/javax/xml/xpath/XPath.html#setNamespaceContext(javax.xml.namespace.NamespaceContext)">
  XPath.setNamespaceContext(NamespaceContext nsContext)</jump>
  method to set the NamespaceContext on the XPath object you create using the <link anchor="basic">basic steps</link>.</p>
  <p>The XPath processor in &xslt4j2; only uses the <jump href="apidocs/javax/xml/namespace/NamespaceContext.html#getNamespaceURI(java.lang.String)">
  getNamespaceURI(String prefix)</jump>
  method on NamespaceContext. The other two methods 
  <jump href="apidocs/javax/xml/namespace/NamespaceContext.html#getPrefix(java.lang.String)">getPrefix(String namespace)</jump>
  and <jump href="apidocs/javax/xml/namespace/NamespaceContext.html#getPrefixes(java.lang.String)">getPrefixes(String namespace)</jump>
  are not used. If the NamespaceContext object is only used by the XPath processor, you can let the unused methods 
  return null for simplicity.</p>
  
  </s2>
  
  <anchor name="variableresolver"/>
  <s2 title="Using XPathVariableResolver">
  <p><jump href="apidocs/javax/xml/xpath/XPathVariableResolver.html">XPathVariableResolver</jump> provides access to the set of user 
  defined XPath variables. If an XPath expression contains
  a variable reference, we need to set a XPathVariableResolver on the XPath object using the 
  <jump href="apidocs/javax/xml/xpath/XPath.html#setXPathVariableResolver(javax.xml.xpath.XPathVariableResolver)">
  XPath.setXPathVariableResolver(XPathVariableResolver resolver)</jump>
  method. You can also set the XPathVariableResolver on the XPathFactory, using the 
  <jump href="apidocs/javax/xml/xpath/XPathFactory.html#setXPathVariableResolver(javax.xml.xpath.XPathVariableResolver)">
  XPathFactory.setXPathVariableResolver(XPathVariableResolver resolver)</jump>
  method. If the XPathVariableResolver is set on the XPathFacory, then all XPath objects constructed from this 
  XPathFactory will use the specified XPathVariableResolver by default. The XPath processor uses the
  XPathVariableResolver to retrieve the value of a user defined variable. In the course of evaluating any 
  single XPath expression, a variable's value must be immutable. </p>
  <p>Suppose that the XPath expression to be evaluated is <code>"$x + $y"</code>, we need to provide a XPathVariableResolver
  implementation from which the values of the variable x and y can be retrieved. For this example, the 
  XPathVariableResolver implementation can be written as follows:</p>
  <source>
    public class MyVariableResolver implements XPathVariableResolver
    {
        public Object resolveVariable(QName var)
        {
            if (var == null)
                throw new NullPointerException("The variable name cannot be null");
              
            if (var.equals(new QName("x")))
                return new Integer(2);
            else if (var.equals(new QName("y")))
                return new Integer(3);
            else
                return null;
        }
    }
  </source>  
  </s2>
  
  <anchor name="functionresolver"/>
  <s2 title="Using XPathFunctionResolver">
  <p><jump href="apidocs/javax/xml/xpath/XPathFunctionResolver.html">XPathFunctionResolver</jump> provides access to the 
  set of user defined XPathFunctions. If an XPath expression contains
  an extension function, you can use the 
  <jump href="apidocs/javax/xml/xpath/XPath.html#setXPathFunctionResolver(javax.xml.xpath.XPathFunctionResolver)">
  XPath.setXPathFunctionResolver(XPathFunctionResolver resolver)</jump>
  method to set a XPathFunctionResolver on the XPath object. You can also use the
  <jump href="apidocs/javax/xml/xpath/XPathFactory.html#setXPathFunctionResolver(javax.xml.xpath.XPathFunctionResolver)">
  XPathFactory.setXPathFunctionResolver(XPathFunctionResolver resolver)</jump>
  method to set a XPathFunctionResolver on the XPathFactory, in which case all XPath objects constructed from this
  XPathFactory will use the specified XPathVariableResolver by default.</p>
  <p>The XPathFunctionResolver interface only has one method:</p>
  <p><jump href="apidocs/javax/xml/xpath/XPathFunctionResolver.html#resolveFunction(javax.xml.namespace.QName, int)">
  <code>public XPathFunction resolveFunction(QName functionName, int arity)</code></jump></p>
  <p>This method returns a XPathFunction object from the given function name and arity. XPath functions are resolved 
  by name and arity. The parameter types have no impact here. XPathFunctionResolver is only used for functions with
  an explicit prefix. It is not needed for XPath built-in functions and it cannot be used to override those functions.</p>
  <p>The XPathFunction interface has only one method:</p>
  <p><jump href="apidocs/javax/xml/xpath/XPathFunction.html#evaluate(java.util.List)">
  <code>public java.lang.Object evaluate(java.util.List args) throws XPathFunctionException</code></jump></p>
  <p>The function parameters are passed in using the args parameter as a java.util.List. And the method returns the result 
  of evaluating the XPath function as an Object.</p>
  <p>To support the use of extension functions in an XPath expression, a user needs to provide implementations of
  the XPathFunctionResolver and XPathFunction interfaces. The resolveFunction method of the XPathFunctionResolver
  implementation should return an object of a class that implements the XPathFunction interface.</p>
  <p>Suppose we want to evaluate the XPath expression <code>"ext:myAdditionFunction(2, 3)"</code>, and the purpose
  of the extension function is simply to return the sum of the two parameters. Because an extension function
  always has an explicit prefix, we also need to implement the NamespaceContext interface to provide a namespace
  prefix to URI mapping. For this example, we need to implement three interfaces: NamespaceContext, 
  XPathFunctionResolver and XPathFunction. A sample implementation is as follows:</p>
  <source>
      public class MyNamespaceContext implements NamespaceContext
      {
          public String getNamespaceURI(String prefix)
          {
              if (prefix == null)
                throw new IllegalArgumentException("The prefix cannot be null.");
              
              if (prefix.equals("ext"))
                  return "http://ext.com";
              else
                  return null;
          }
          
          public String getPrefix(String namespace)
          {
              if (namespace == null)
                throw new IllegalArgumentException("The namespace uri cannot be null.");
              if (namespace.equals("http://ext.com"))
                return "ext";
              else
                return null;
          }
  
          public Iterator getPrefixes(String namespace)
          {
              return null;
          }
      }
      
      /**
       * The XPathFunctionResolver implementation is used to evaluate
       * the extension function "ext:myAdditionFunction(2, 3)".
       */
      public class MyFunctionResolver implements XPathFunctionResolver
      {
      	/**
      	 * This method returns a customized XPathFunction implementation
      	 * for the extension function "ext:myAdditionFunction(2, 3)".
      	 */
      	public XPathFunction resolveFunction(QName fname, int arity)
      	{
      	  if (fname == null)
      	    throw new NullPointerException("The function name cannot be null.");
      	  
      	  // We only recognize one function, i.e. ex:addFunc().
      	  if (fname.equals(new QName("http://ext.com", "myAdditionFunction", "ext")))
      	    /** 
      	     * Return a customized implementation of XPathFunction. We need
      	     * to implement the evaluate(List) method.
      	     */
      	    return new XPathFunction() {
      	      /**
      	       * The actual implementation of the extension function.
      	       * Just cast two arguments to Double and add them together.
      	       */
      	      public Object evaluate(java.util.List args) {
      	        if (args.size() == 2) {
      	          Double arg1 = (Double)args.get(0);
      	          Double arg2 = (Double)args.get(1);
      	          return new Double(arg1.doubleValue() + arg2.doubleValue());
      	        }
      	        else
      	          return null;
      	      }
      	    };
      	  else
      	    return null;
      	}
      }
  </source>
  </s2>
  
  <anchor name="sampleresolver"/>
  <s2 title="Using the sample XPathFunctionResolver">
  <p>Normally you need to provide your own implementation of XPathFunctionResolver in order to use
  extension functions in XPath expressions. In &xslt4j2;, we provide a sample implementation 
  of XPathFunctionResolver in the class org.apache.xalan.extensions.XPathFunctionResolverImpl, with supports
  for Java and EXSLT extensions. If you set the XPathFunctionResolver to an object of this class, then
  you can use Java and EXSLT extension functions in the XPath expression. You also need to use a
  NamespaceContext along with the sample XPathFunctionResolver. &xslt4j2; also includes a sample 
  implementation of NamespaceContext in org.apache.xalan.extensions.ExtensionNamespaceContext, which 
  provides the following namespace prefix to URI mappings:</p>
  
  <table>
  <tr>
    <th>Prefix</th>
    <th>URI</th>
  </tr>
  <tr>
    <td>java</td>
    <td>http://xml.apache.org/xalan/java</td>
  </tr>
  <tr>
    <td>exslt</td>
    <td>http://exslt.org/common</td>
  </tr>
  <tr>
    <td>math</td>
    <td>http://exslt.org/math</td>
  </tr>
  <tr>
    <td>set</td>
    <td>http://exslt.org/sets</td>
  </tr>
  <tr>
    <td>str</td>
    <td>http://exslt.org/strings</td>
  </tr>
  <tr>
    <td>dyn</td>
    <td>http://exslt.org/dynamic</td>
  </tr>
  <tr>
    <td>datetime</td>
    <td>http://exslt.org/dates-and-times</td>
  </tr>
  </table>
  
  <p>Suppose you want to evaluate the XPath expression <code>"math:max(/doc/num)"</code>, which contains
  an EXSLT extension call. Here the prefix <code>"math"</code> corresponds to the URI <code>"http://exslt.org/math"</code>. 
  The following code snippet demonstrates how to use the sample XPathFunctionResolver to evaluate the 
  XPath expression above:</p>
  <source>
        XPathFactory factory = XPathFactory.newInstance();
        XPath xpath = factory.newXPath();
        
        // set the NamespaceContext to 
        // org.apache.xalan.extensions.ExtensionNamespaceContext
        xpath.setNamespaceContext(new org.apache.xalan.extensions.ExtensionNamespaceContext());
        
        // set the XPathFunctionResolver to 
        // org.apache.xalan.extensions.XPathFunctionResolverImpl
        xpath.setXPathFunctionResolver(new org.apache.xalan.extensions.XPathFunctionResolverImpl());
        
        // Evaluate the XPath expression "math:max(/doc/num)" against 
        // the input document numlist.xml
        Object result = xpath.evaluate("math:max(/doc/num)", new InputSource("numlist.xml"), XPathConstants.NUMBER);  
  </source>
  </s2>
</s1>
