XQuery での外部関数の使用

外部関数を使用する XQuery 式を使用する場合は、外部関数として XQuery Prolog に、または XStaticContext インスタンスを使用して関数シグニチャーを宣言します。各関数には、XDynamicContext インスタンスを使用して Java 実装を指定 (またはバインド) します。

手順

  1. 外部関数を使用する XQuery 式を作成する場合は、XQuery Prolog に、または XStaticContext インスタンスを使用して関数シグニチャーを宣言します。

    XStaticContext で宣言された関数は、メイン・モジュールに対してのみ可視になります。 外部関数をライブラリー・モジュールに可視にするには、ライブラリー・モジュールの Prolog でその関数を宣言する必要があります。

    XStaticContext インターフェースには 2 つの declareFunction メソッドがあります。各メソッドには 3 つのパラメーターがあり、名前、関数の戻りの型、および引数の型の配列を示します。 名前は常に QName オブジェクトとして指定されますが、型には、QName または XSequenceType を指定できます。関数名、戻りの型、および引数の型によって、関数を一意的に識別する必要があります。

    表 1. XStaticContext declareFunction メソッド.

    以下の表に、declareFunction メソッドの各書式を使用する時機を示します。

    メソッド・シグニチャー 目的
    declareFunction(QName 名、QName 型、QName[] argTypes) 関数の戻り値と引数がすべて単一のアトミック値である場合に使用します。

    QName 型は、組み込み型、あるいは XStaticContext インスタンスの作成に使用される XFactory インスタンスに登録済みのスキーマ内で宣言されたグローバル型を参照します。QName がアトミック以外の型を参照する場合、プロセッサーはそれを element(*, ns:type) 型として扱います。ここで、ns:type は所定の QName です。XTypeConstants インターフェースには、 組み込みの型ごとに QName オブジェクトを指定できる便利な定数があります。

    declareFunction(QName 名、XSequenceType 型、XSequenceType[] argTypes) 関数の引数のいずれかまたは戻り値が、単一のノード、あるいはアトミック値またはノードのシーケンスである場合に使用します。
    以下の XQuery 式では 3 つの関数を使用します。そのうちの 2 つは Prolog に宣言されています。
    declare namespace xs = "http://www.w3.org/2001/XMLSchema";
    declare namespace trig = "http://www.example.org/trigonometry";
    declare function trig:arctan($ratio as xs:double) as xs:double external;
    declare function trig:sin($angle as xs:double) as xs:double external;
    
    <ramps>
    {
        for $ramp in ramps/ramp
        let $angleRadians := trig:arctan($ramp/height div $ramp/base)
        let $angle := trig:toDegrees($angleRadians)
        let $length := $ramp/height div trig:sin($angleRadians)
        return
            element ramp
            {
                $ramp/height,
                $ramp/base,
                element angle { $angle },
                element length { $length }
            }
    }
    </ramps>
    該当の照会が xquerySource ソース・オブジェクトを使用して使用可能であると仮定すると、以下のコードで照会が作成されます。照会自体で宣言されなかった関数 trig:toDegrees は、XStaticContext インスタンスで宣言されます。
    // Create the factory
    XFactory factory = XFactory.newInstance();
    
    // Create a new static context
    XStaticContext staticContext = factory.newStaticContext();
    
    // Declare a namespace for the functions
    staticContext.declareNamespace("trig", "http://www.example.org/trigonometry");
    
    // Create a QName for the trig:toDegrees function
    QName toDegreesQName = new QName("http://www.example.org/trigonometry", "toDegrees");
    
    // Declare the function on the static context
    staticContext.declareFunction(toDegreesQName, XTypeConstants.DOUBLE_QNAME, new QName[]{XTypeConstants.DOUBLE_QNAME});
    
    // Create an XQuery executable for the query
    XQueryExecutable executable = factory.prepareXQuery(xquerySource, staticContext);
  2. 外部関数を使用する XQuery 式を実行するには、XDynamicContext インスタンスを使用して関数を実装する Java メソッドを指定 (またはバインド) します。

    外部関数のバインディングは、メイン・モジュールならびに、その関数の Prolog で外部関数宣言をしているすべてのライブラリー・モジュールで使用可能になります。

    Java リフレクションを使用して、関数の java.lang.reflect.Method オブジェクトを取得します。メソッドがインスタンス・メソッドである場合は、 この関数のバインド時にインスタンス・オブジェクトが必要となります。

    XQuery 式の実行時に使用される関数に Java メソッドが指定されていない場合は、エラーが表示されます。

    XDynamicContext には 2 つの bindFunction メソッドがあります。 各メソッドには、関数の名前に対応する QName オブジェクトと、関数の実装を提供する Java メソッドを識別する Method オブジェクトが必要です。
    表 2. XDynamicContext bindFunction メソッド.

    この表に、XDynamicContext bindFunction メソッドの各書式を使用する時機を示します。

    メソッド名 目的
    bindFunction(QName qname、Method メソッド) 静的メソッドをバインドするときに使用します。
    bindFunction(QName qname、Method メソッド、Object instanceObject) インスタンス・メソッドをバインドするときに使用します。
    以下の例は、まず最初に、関数に使用されるメソッドをバインドしてから、1 番目の例で作成された XQuery 式を実行したものです。 この例では、java.lang.Math クラスの静的メソッドである atan、sin、および toDegrees が、外部関数の実装を提供するために使用されています。
    // Create a new dynamic context
    XDynamicContext dynamicContext = factory.newDynamicContext();
    
    // Retrieve the java.lang.reflect.Method object for the trig:toDegrees function
    Method toDegreesMethod = Math.class.getMethod("toDegrees", Double.TYPE);
    
    // Bind the function to the dynamic context
    dynamicContext.bindFunction(toDegreesQName, toDegreesMethod);
    
    // Create QNames for the trig:arctan and trig:sin functions
    QName arctanQName = new QName("http://www.example.org/trigonometry", "arctan");
    QName sinQName = new QName("http://www.example.org/trigonometry", "sin");
    
    // Retrieve the java.lang.reflect.Method objects for the trig:arctan and trig:sin functions
    // then bind them to the dynamic context
    Method arctanMethod = Math.class.getMethod("atan", Double.TYPE);
    Method sinMethod = Math.class.getMethod("sin", Double.TYPE);
    dynamicContext.bindFunction(arctanQName, arctanMethod);
    dynamicContext.bindFunction(sinQName, sinMethod);
    
    // Create an XML input document
    String xml = "<ramps>" +
    "<ramp><base>4</base><height>4</height></ramp>" +
    "<ramp><base>4</base><height>3</height></ramp>" +
    "<ramp><base>10</base><height>2</height></ramp>" +
    "</ramps>";
    StreamSource source = new StreamSource(new StringReader(xml));
    
    // Execute the query
    XSequenceCursor result = executable.execute(source, dynamicContext);
     
    // Serialize the result to System.out
    result.exportItem(new StreamResult(System.out));

トピックのタイプを示すアイコン タスク・トピック



タイム・スタンプ・アイコン 最終更新: last_date
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=txml_funcs_xquery
ファイル名:txml_funcs_xquery.html