0

XPath 3.1transform函数允许您应用模板或调用命名模板或调用样式表函数。

但是,当我尝试使用现有的 XSLT 2.0 样式表模块时(例如,在 http://www.xsltfunctions.com/ 上记录的 functx 模块并在http://www.xsltfunctions.com/作为 XSLT 2 提供xsl/functx-1.0-doc-2007-01.xslxsl:stylesheet )在一个或xsl:transform根元素中以 XSLT 2 方式声明许多函数,但不使用 XSLT 3xsl:package构造,我无法说服 Saxon 9.8 或 9.9 运行任何使用transform函数和参数声明的函数,initial-function因为我总是收到错误“ XTDE0041:无法从外部调用函数 foo#2,因为它不是公共的”。

示例可能是:

transform(
map {
'stylesheet-location': 'http://www.xsltfunctions.com/xsl/functx-1.0-doc-2007-01.xsl',
'delivery-format': 'raw',
'initial-function': QName('http://www.functx.com', 'substring-before-match'),
'function-params': ['abc-def-ghi', '[dg]']
})?output

但给出了上述错误。

我发现的唯一解决方法是动态构建(例如在 XQuery 中)一个 XSLT 3 包,导入 functx 模块并xsl:expose用于公开函数:

let $functxNs := 'http://www.functx.com',
    $functxLoc := 'http://www.xsltfunctions.com/xsl/functx-1.0-doc-2007-01.xsl',
    $libPackage := <xsl:package
        name="http://example.com/import-functx"
        package-version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        version="3.0"
        xmlns:functx="http://www.functx.com">
        <xsl:expose
            component="function"
            names="functx:*"
            visibility="public"/>
        <xsl:import
            href="{$functxLoc}"/>
    </xsl:package>
return
    transform(
    map {
        'stylesheet-node': $libPackage,
        'delivery-format': 'raw',
        'initial-function': QName('http://www.functx.com', 'substring-before-match'),
        'function-params': ['abc-def-ghi', '[dg]']
    })?output

这可行,但需要使用 XPath 3.1 的宿主语言(如上面的 XQuery 3.1)。

有没有更简单的方法来使用该transform函数并initial-function使用现有的 XSLT 2 样式表模块声明函数?

4

1 回答 1

0

根据 Michael Kay 在https://saxonica.plan.io/boards/3/topics/7540visibility中的解释,默认情况下,任何没有属性的命名函数都被fn:transform执行样式表的函数视为私有,无论该函数出现在显式包中还是在一个隐含的(即带有xsl:stylesheetor的样式表模块xsl:transform)中。

基于此,确实需要重写 XSLT 2 代码以添加visibility应该由fn:transform执行调用的函数的属性,或者需要将现有 XSLT 2 代码“包装”到允许更改可见性的 XSLT 3 构造中,就像我在我尝试导入 XSLT 2 代码xsl:import并使用它xsl:expose来确保导入的函数由例如公开<xsl:expose component="function" names="functx:*" visibility="public"/>。然而,除了 XPath 3.1 之外,后者还需要使用 XSLT 3 或 XQuery 3 fn:transform

于 2019-07-31T08:01:42.597 回答