File: xpath_apis.xml

package info (click to toggle)
libxalan2-java 2.7.2-4
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, sid, trixie
  • size: 19,608 kB
  • sloc: java: 175,006; xml: 28,206; sh: 159; jsp: 43; makefile: 12; sql: 6
file content (400 lines) | stat: -rw-r--r-- 21,687 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
<?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>