Как представить функции, определенные в модуле таблицы стилей 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
,