Using query-declared external functions with XQuery
As an alternative to binding Java™ methods to functions in a query using the API, Java external functions can be declared directly within a query. The only additional configuration required is for bound Java classes to exist on the classpath during query execution.
Procedure
declare option xltxe:java-extension "prefix = className";
prefix:methodName(Params*)
Example
Invoking Static Methods
declare namespace calc="http://com.example/myApp/Calculator";
declare namespace sf="http://com.example/myApp/standardFormat";
declare namespace xltxe="http://www.ibm.com/xmlns/prod/xltxe-j";
declare option xltxe:java-extension "calc = org.company.Calculator";
declare option xltxe:java-extension "sf = org.standards.Formatter";
sf:format(calc:sqrt(64), "ISO-42.7")
// Create the factory
XFactory factory = XFactory.newInstance();
// Create an XQuery executable for the query
XQueryExecutable executable = factory.prepareXQuery(xquerySource);
// Create a result object to store the transformation result
Result result = new StreamResult(System.out);
// Execute the XSLT executable
XSequenceCursor xsc = executable.execute();
// Output the result
xsc.exportSequence(res);
The example query provided assumes that the org.company.Calculator class contains a static method sqrt() that takes one parameter and the org.standards.Formatter class contains a static method format() that takes two parameters. At prepare time, the classes are not required on the classpath; but they are required during execution of the query.
package org.company;
public class Calculator {
public static int sqrt(int val) {
return (int)Math.sqrt(val);
}
package org.standards;
public class Formatter {
public static String format(int val, String pattern) {
return "Formatting " + val + " using pattern " + pattern;
}
}
Invoking Instance Methods
prefix:new(Params*)
declare namespace car="http://com.example/myApp/car";
declare namespace xltxe="http://www.ibm.com/xmlns/prod/xltxe-j";
declare option xltxe:java-extension "car = org.automobile.Car";
declare variable $var := car:new(3);
car:getDoors($var)
// Create the factory
XFactory factory = XFactory.newInstance();
// Create an XQuery executable for the query
XQueryExecutable executable = factory.prepareXQuery(xquerySource);
// Create a result object to store the transformation result
Result result = new StreamResult(System.out);
// Execute the XSLT executable
XSequenceCursor xsc = executable.execute();
// Output the result
xsc.exportSequence(res);
The example query assumes that org.automobile.Car class contains a constructor that takes an argument of type int. In addition, the org.automobile.Car class also contains an instance method getDoors() that takes no arguments. The syntax for invoking instance methods from query-declared external functions require that the created instance object be passed in as the first argument.
package org.automobile;
public class Car {
private int doors;
public Car (int doors) {
this.doors = doors;
}
public int getDoors() {
return doors;
}
}
declare namespace car="http://com.example/myApp/car";
declare namespace sedan="http://com.example/myApp/sedan";
declare namespace xltxe="http://www.ibm.com/xmlns/prod/xltxe-j";
declare option xltxe:java-extension "car = org.automobile.Car";
declare option xltxe:java-extension "sedan = org.automobile.Sedan";
declare variable $var := sedan:new(5);
car:getDoors($var)
package org.automobile;
public class Sedan extends Car {
public Sedan (int doors) {
super(doors);
}
}