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 interface is very efficient but performs less
validation of parameters than the standard interface described above. To achieve this,
first compile the query as described above, specifying a query that includes one or more
declare function
declarations in the query prolog. It is then possible to
retrieve the UserFunction
objects representing the compiled code of these
functions, by calling the getUserDefinedFunction
method on the
StaticQueryContext
object. As discussed above, the information is not held
in the original StaticQueryContext
object (which Saxon does not alter), but in
a modified copy which is obtainable from the XQueryExpression
object. Once
found, such a function can be called using its call
method. The first argument
to this is an array containing the values of the arguments. These must be supplied using
Saxon's native classes, for example an integer argument is supplied as an instance of IntegerValue
. These values
must be of the type expected by the function; no conversion or type checking takes place
(which means that a ClassCastException
will probably occur if the wrong type
of value is supplied). The second argument to the call
method is a Controller
. A
Controller
can be obtained by calling the getController()
method on the XQueryExpression
object. The same Controller
can be
used for a series of separate function calls.
For example:
Configuration config = new Configuration(); StaticQueryContext sqc = config.newStaticQueryContext(); XQueryExpression exp1 = sqc.compileQuery( "declare namespace f='f.ns';" + "declare function f:t1($p as xs:integer) { $p * $p };" + "declare function f:t2($p as xs:integer) { $p + $p };" + "1" ); StaticQueryContext sqc2 = exp1.getStaticContext(); UserFunction fn1 = sqc2.getUserDefinedFunction("f.ns", "t1", 1); UserFunction fn2 = sqc2.getUserDefinedFunction("f.ns", "t2", 1); Controller controller = exp1.getController(); IntegerValue[] arglist = new IntegerValue[1]; for (int x=1; x<1000000; x++) { arglist[0] = new IntegerValue(x); Value v1 = fn1.call(arglist, controller); Value v2 = fn2.call(arglist, controller); System.err.println("Returned product " + v1 + "; sum =" + v2); }