XSLT でのスタイル・シート内宣言の外部関数の使用
API を使用してスタイル・シート内の関数に Java™ メソッドをバインディングする代わりに、Java 外部関数をスタイル・シート内に直接宣言することができます。 必要な追加構成は、バインド済み Java クラスが、スタイル・シートの実行中にクラスパス上に存在するようにすることだけです。
手順
Java 拡張エレメントを使用して、Java クラスに接頭部をバインドすることができます。
<xltxe:java-extension
prefix = string
class = string />
注: http://www.ibm.com/xmlns/prod/xltxe-j 名前空間にバインドされている限り、任意の接頭部の名前を Java 拡張エレメントに使用することができます。
接頭部を
Java クラスにバインディングしたら、バインド済みクラス内のメソッドは、接頭部とメソッド名をコロンで区切って指定することで呼び出すことができます。
prefix:methodName(Params*)
例
静的メソッドの呼び出し
スタイル・シート内宣言の外部関数を使用する XSLT スタイル・シートを作成する場合は、
Java クラス・バインディングに対する接頭部を宣言します。
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xltxe="http://www.ibm.com/xmlns/prod/xltxe-j"
xmlns:calc="http://com.example/myApp/calculator"
xmlns:sf="http://com.example/myApp/standardFormat">
<xltxe:java-extension prefix="calc" class="org.company.Calculator"/>
<xltxe:java-extension prefix="sf" class="org.standards.Formatter"/>
<xsl:template match="/">
<xsl:value-of select="sf:format(calc:sqrt(64), 'ISO-42.7')"/>
</xsl:template>
</xsl:stylesheet>
このスタイル・シートが xsltSource ソース・オブジェクトによって使用可能であると仮定すると、以下のコードでスタイル・シートが作成されます。
// Create the factory
XFactory factory = XFactory.newInstance();
// Create an XSLT executable for the stylesheet
XSLTExecutable executable = factory.prepareXSLT(xsltSource);
以下のコードは、この例で作成されたスタイル・シートを実行します。
// Create the xml input
String xml = "<doc/>";
// Create a result object to store the transformation result
Result result = new StreamResult(System.out);
// Execute the XSLT executable
executable.execute(new StreamSource(new ByteArrayInputStream(xml.getBytes())), result);
用意したサンプルのスタイル・シートは、 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*)
その結果は、以下のスタイル・シートに示すように、xsl:variable エレメントに保管することができます。
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xltxe="http://www.ibm.com/xmlns/prod/xltxe-j"
xmlns:car="http://com.example/myApp/car">
<xltxe:java-extension prefix="car" class="org.automobile.Car"/>
<xsl:variable name="var" select="car:new(3)"/>
<xsl:template match="/">
<xsl:value-of select="car:getDoors($var)"/>
</xsl:template>
</xsl:stylesheet>
このスタイル・シートが xsltSource ソース・オブジェクトによって使用可能であると仮定すると、以下のコードでスタイル・シートが作成されます。
// Create the factory
XFactory factory = XFactory.newInstance();
// Create an XSLT executable for the stylesheet
XSLTExecutable executable = factory.prepareXSLT(xsltSource);
以下のコードは、この例で作成されたスタイル・シートを実行します。
// Create the xml input
String xml = "<doc/>";
// Create a result object to store the transformation result
Result result = new StreamResult(System.out);
// Execute the XSLT executable
executable.execute(new StreamSource(new ByteArrayInputStream(xml.getBytes())), result);
このサンプル・スタイル・シートは、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 内のメソッドを呼び出すことができます。
この例を次のスタイル・シートで示します。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xltxe="http://www.ibm.com/xmlns/prod/xltxe-j"
xmlns:sedan="http://com.example/myApp/sedan"
xmlns:car="http://com.example/myApp/car">
<xltxe:java-extension prefix="sedan" class="org.automobile.Sedan"/>
<xltxe:java-extension prefix="car" class="org.automobile.Car"/>
<xsl:variable name="var" select="sedan:new(5)"/>
<xsl:template match="/">
<xsl:value-of select="car:getDoors($var)"/>
</xsl:template>
</xsl:stylesheet>
以下は、org.automobile.Sedan の実装例です。
package org.automobile;
public class Sedan extends Car {
public Sedan (int doors) {
super(doors);
}
}
Limitation: Java クラスでメソッドの解決に使用されるメカニズムでは、名前とアリティーが一致しているメソッドが一つのみ存在することが必要です。
同じ名前で異なるアリティーの複数のメソッドが存在すると、エラーがスローされます。