Как представить функции, определенные в модуле таблицы стилей XSLT 2, для fn:transform?

XPath 3.1 transform функции позволяют применять шаблоны или вызывать именованный шаблон или вызывать функцию таблицы стилей.

Однако, когда я пытаюсь использовать существующий модуль таблицы стилей XSLT 2.0 (например, модуль functx, описанный по адресу http://www.xsltfunctions.com/ и доступный как XSLT 2 по адресу http://www.xsltfunctions.com/xsl/functx-1.0-doc-2007-01.xsl) объявление множества функций способом XSLT 2 в пределах xsl:stylesheet или же xsl:transform корневой элемент, но без использования XSLT 3 xsl: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, объявляющими функции?

1 ответ

Решение

На основе объяснений Майкла Кея в https://saxonica.plan.io/boards/3/topics/7540 любой именованной функции без visibility атрибут по умолчанию считается закрытым fn:transform функция, выполняющая таблицу стилей, независимо от того, появляется ли функция в явном пакете или в неявном (т.е. в модуле таблицы стилей с xsl:stylesheet или же 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"/>, Последнее, однако, требует использования XSLT 3 или XQuery 3 в дополнение к XPath 3.1 fn:transform,

Другие вопросы по тегам