Utilización de funciones externas declaradas en consultas con XQuery
Como alternativa al enlace de métodos Java™ con funciones en una consulta utilizando la API, las funciones externas Java se pueden declarar directamente dentro de una consulta. La única configuración adicional necesaria es que las clases Java enlazadas estén en la vía de acceso de clases durante la ejecución de la consulta.
Procedimiento
declare option xltxe:java-extension "prefijo = nombreClase";
prefijo:nombreMétodo(Params*)
Ejemplo
Invocación de métodos estáticos
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);
La consulta de ejemplo proporcionada presupone que la clase org.company.Calculator contiene un método estático sqrt() que toma un parámetro y la clase org.standards.Formatter contiene un método estático format() que toma dos parámetros. Durante la preparación, no son necesarias las clases en la vía de acceso de clases, pero sí son necesarias durante la ejecución de la consulta.
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;
}
}
Invocación de métodos de instancia
prefijo: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);
La consulta de ejemplo supone que la clase org.automobile.Car contiene un constructor que toma un argumento de tipo int. Además, la clase org.automobile.Car también contiene un método de instancia getDoors() que no toma argumentos. La sintaxis para invocar métodos de instancia de funciones externas declaradas en consulta requiere que el objeto de instancia creado se pase como el primer argumento.
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);
}
}