将外部函数用于 XQuery

使用 XQuery 表达式(使用了外部函数)时,在 XQuery Prolog 中将函数特征符作为外部函数进行声明,或使用 XStaticContext 实例声明外部函数。使用 XDynamicContext 实例为各个函数提供(或绑定)Java 实现。

过程

  1. 准备 XQuery 表达式(使用了外部函数)时,在 XQuery Prolog 中声明函数特征符,或使用 XStaticContext 实例声明函数特征符。

    XStaticContext 中声明的函数仅对于主模块可见。要使外部函数对于库模块可见,必须在该库模块的 Prolog 中声明此外部函数。

    XStaticContext 接口具有两种 declareFunction 方法,每种方法具有三个参数:一个参数用于名称,一个参数用于函数的返回类型,一个数组用于自变量的类型。始终将名称作为 QName 对象提供,但类型可以为 QNames 或 XSequenceTypes。函数名称、返回类型和自变量类型必须唯一标识该函数。

    表 1. XStaticContext declareFunction 方法.

    此表说明何时使用各种格式的 declareFunction 方法。

    方法特征符 用途
    declareFunction(QName name, QName type, QName[] argTypes) 用于当函数的返回值和自变量都为单一原子值的情况

    类型 QName 必须引用模式中声明的内置类型或全局类型,此模式已在用于创建 XStaticContext 实例的 XFactory 实例上注册。如果 QName 引用非原子类型,那么处理器会将其视为 type 元素 (*, ns:type),其中 ns:type 是给定的 QName。XTypeConstants 接口具有可用的方便常量,这些常量为各种内置类型提供 QName 对象。

    declareFunction(QName name, XSequenceType type, XSequenceType[] argTypes) 用于在函数的任何自变量或返回值为节点、原子值序列或节点序列的情况
    以下 XQuery 表达式使用三个函数,其中两个在 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 具有两种 bindFunction 方法。每种方法需要对应于该函数的名称的 QName 对象,以及标识将提供此函数的实现的 Java 方法的方法对象。
    表 2. XDynamicContext bindFunction 方法.

    此表说明何时使用各种格式的 XDynamicContext bindFunction 方法。

    方法名 用途
    bindFunction(QName qname, Method method) 用于绑定静态方法的情况
    bindFunction(QName qname, Method method, Object instanceObject) 用于绑定实例方法的情况
    以下示例执行第一个示例中准备的 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