XQuery での照会内宣言の外部関数の使用
API を使用して照会内の関数に Java™ メソッドをバインディングする代わりに、 Java 外部関数を照会内に直接宣言することができます。 必要な追加構成は、バインド済み Java クラスが、照会の実行中にクラスパス上に存在するようにすることだけです。
手順
Java 拡張 XQuery オプション宣言を使用して、Java クラスに接頭部をバインドすることができます。
declare option xltxe:java-extension "prefix = className";
注: http://www.ibm.com/xmlns/prod/xltxe-j 名前空間にバインドされている限り、任意の接頭部の名前を Java 拡張エレメントに使用することができます。
接頭部を
Java クラスにバインディングしたら、バインド済みクラス内のメソッドは、接頭部とメソッド名をコロンで区切って指定することで呼び出すことができます。
prefix:methodName(Params*)
例
静的メソッドの呼び出し
照会内宣言の外部関数を使用する XQuery ソースを作成する場合は、
Java クラス・バインディングに対する接頭部を宣言します。
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")
この照会が xquerySource ソース・オブジェクトによって使用可能であると仮定すると、以下のコードで照会が作成されます。
// 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);
用意したサンプルの照会は、org.company.Calculator クラスに、パラメーターを 1 つ取る静的メソッドの sqrt() が含まれていること、および org.standards.Formatter クラスに、パラメーターを 2 つ取る静的メソッド format() が含まれていることを前提としています。 作成時には、それらのクラスがクラスパス上にある必要はありませんが、照会の実行時にはその必要があります。
以下は、org.company.Calculator クラスと org.standards.Formatter クラスの実装例です。
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;
}
}
インスタンス・メソッドの呼び出し
クラスからのインスタンス・メソッドの呼び出しは、インスタンス・オブジェクトが必要であるという点で、静的メソッドの呼び出しと少し異なります。
照会内で Java クラスからインスタンス・オブジェクトを取得するには、新しいコンストラクターを呼び出す必要があります。
prefix:new(Params*)
その結果は、以下の照会に示すように、XQuery 変数宣言に保管することができます。
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)
この照会が xquerySource ソース・オブジェクトによって使用可能であると仮定すると、以下のコードで照会が作成されます。
// 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);
このサンプル照会は、org.automobile.Car クラスに、タイプ int の引数を取るコンストラクターが含まれていることを前提としています。 さらに、org.automobile.Car クラスには、引数を取らないインスタンス・メソッドの getDoors() も含まれています。 照会内宣言の外部関数からインスタンス・メソッドを呼び出す構文では、作成されたインスタンス・オブジェクトが最初の引数として受け渡されることが必要となります。
以下に、org.automobile.Car クラスの実装例を示します。
package org.automobile;
public class Car {
private int doors;
public Car (int doors) {
this.doors = doors;
}
public int getDoors() {
return doors;
}
}
インスタンス・メソッドを使用した継承もサポートされています。
org.automobile.Car クラスに org.automobile.Sedan というサブクラスがある場合、
org.automobile.Sedan クラスのインスタンスを作成し、それを使用して org.automobile.Car 内のメソッドを呼び出すことができます。
この例を次の照会で示します。
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)
以下は、org.automobile.Sedan の実装例です。
package org.automobile;
public class Sedan extends Car {
public Sedan (int doors) {
super(doors);
}
}
Limitation: Java クラスでメソッドの解決に使用されるメカニズムでは、名前とアリティーが一致しているメソッドが一つのみ存在することが必要です。
同じ名前で異なるアリティーの複数のメソッドが存在すると、エラーがスローされます。