Calling XQuery Functions from Java
Although the usual way to invoke XQuery from a Java application is to compile and execute a query as described above, it is also possible to invoke individual XQuery functions directly from Java if required. This is achieved as follows:
-
First use the s9api interface to create an
XQueryEvaluator
in the usual way -
Use methods such as
setContextItem()
andsetExternalVariable()
to supply any information needed by the query -
Then instead of calling the
run()
method on theXQueryEvaluator
to execute the query, call the methodcallFunction()
to execute a specific function.
The third step can be repeated to call different functions or to call the same function with different parameters. Having called a function, the context item and external variable values should not be changed.
A function in a query is identified uniquely by a QName and arity. The QName is supplied explicitly in the call on
callFunction()
; the arity is inferred from the length of the argument array.
The arguments to the function are supplied as an array of XdmValue
objects, and the result is returned
as an XdmValue
. The XdmValue
class has subclasses such as XdmNode
, XdmAtomicValue
,
and XdmMap
allowing specific types of value to be constructed; it is also possible, of course, to use the
result of one function call as an argument to another function call.
Saxon applies the standard function conversion rules to convert supplied arguments to the required type: for example, if the function expects a string, then you can supply an attribute node, and it will be atomized.
Here is an example:
Processor processor = new Processor(true); XQueryCompiler qc = processor.newXQueryCompiler(); XQueryExecutable exp1 = qc.compile( "declare function local:t1($v1 as xs:integer, $v2 as xs:double*) { " + " $v1 div sum($v2)" + "};" + "10"); final XQueryEvaluator ev = exp1.load(); XdmValue v1 = new XdmAtomicValue(14); XdmValue v2 = new XdmAtomicValue(5).append(new XdmAtomicValue(2)); XdmValue result = ev.callFunction(new QName("http://www.w3.org/2005/xquery-local-functions", "t1"), new XdmValue[]{v1, v2});The value of result
will be the atomic value 2, of type xs:double
. The function conversion rules take care of
the fact that a supplied sequence of integers is accepted where the required type is a sequence of xs:double
values.