xsl:function¶
Определяет функцию в таблице стилей. Функция записывается в XSLT, но может быть вызвана из любого выражения XPath в таблице стилей. Она должна иметь префикс пространства имен не по умолчанию.
Доступна в XSLT 2.0 и более поздних версиях. Доступен во всех изданиях Saxon.
- Категория: declaration
- Содержимое: (
xsl:param
* , sequence-constructor ) - Допустимые родительские элементы:
xsl:package
;xsl:stylesheet
;xsl:transform
;xsl:override
Атрибуты¶
name
- eqname
- Имя функции. Должно находиться в пространстве имен не по умолчанию.
as?
- sequence-type
- Определяет тип возврата функции.
visibility?
"public" | "private" | "final" | "abstract"
- Новое в XSLT 3.0. Определяет видимость функции в других пакетах.
streamability?
"unclassified" | "absorbing" | "inspection" | "filter" | "shallow-descent" | "deep-descent" | "ascent" | eqname
- Не реализовано в Saxon 9.7.
override-extension-function?
- boolean
- Определяет, что произойдет, если эта функция имеет то же имя и степень сложности, что и другая, предоставленная реализацией или доступная в статическом контексте с помощью механизма, определенного реализацией. Если значение равно yes (по умолчанию), то эта функция имеет приоритет; если значение равно no, то приоритет имеет другая функция.
[override]?
- boolean
- Устаревший синоним
override-extension-function
, сохраненный для совместимости с XSLT 2.0. new-each-time?
"yes" | "true" | "1" | "no" | "false" | "0" | "maybe"
- Приписывает функцию к одной из трех категорий относительно детерминизма функций (актуально для оптимизации). Значение no означает, что функция детерминирована; значение yes означает, что она активна; а значение may означает, что она неуловима. Требуется Saxon-PE или Saxon-EE.
cache?
- boolean
- Указывает, должна ли функция кэшировать свои результаты. Требуется Saxon-PE или Saxon-EE.
saxon:as?
- sequence-type
- Позволяет предоставлять дополнительную информацию о типе, используя синтаксис расширения Saxon.
saxon:memo-function?
- boolean
- Указание "да" означает, что Saxon должен запомнить результаты вызова функции в кэше, и при повторном вызове функции с теми же аргументами результат будет получен из кэша, а не пересчитан. Требуется Saxon-PE или Saxon-EE.
Заметки по реализации Saxon¶
Saxon определяет дополнительный атрибут для xsl:function
, а именно saxon:memo-function
. Атрибут saxon:memo-function="yes"
указывает, что Saxon должен запомнить результаты вызова функции в кэше, и если функция будет вызвана снова с теми же аргументами, результат будет получен из кэша, а не пересчитан.
Атрибут расширения saxon:explain
также может быть использован для элемента xsl:function
. Если атрибут имеет значение yes
, то во время компиляции Saxon выводит (в стандартный вывод ошибок) представление оптимизированного дерева выражений для этой функции.
Атрибуты cache
и new-each-time
интерпретируются в Saxon 9.7 (PE или выше) следующим образом: если значение cache
равно yes
, или значение new-each-time
равно no
, то функция реализуется как memo функция, так же, как и при установке атрибута расширения saxon:memo-function
. Обратите внимание, что кэш, используемый для мемо-функции в Saxon 9.7, всегда является полным кэшем, то есть он сохраняет результаты всех предыдущих вызовов функции в пределах области действия запроса или преобразования. В Saxon-HE эти атрибуты не имеют никакого эффекта.
Атрибут visibility
реализован начиная с Saxon 9.6 как часть реализации пакетов XSLT 3.0.
В Saxon 9.8 появилась поддержка потоковых функций таблицы стилей, основанная на новом атрибуте XSLT 3.0 streamability
. Тестовое покрытие для этой функции на момент выпуска довольно скудное.
Подробности¶
В ограниченных обстоятельствах функции таблицы стилей (xsl:function
) оптимизируют хвостовую рекурсию. Обстоятельства заключаются в том, что выражение select
инструкции xsl:sequence
, которая представляет собой вложенный конструктор последовательности, должно содержать вызов той же функции, что и then
или else
часть условного выражения (которое может быть вложено в другие условные выражения). Написание функций для использования этого может потребовать некоторой осторожности. См. примеры ниже.
Примеры¶
Пример 1¶
Следующий пример не является хвостовым рекурсивным, поскольку рекурсивный вызов находится внутри арифметического выражения: умножение происходит при возврате из рекурсивного вызова.
1 2 3 4 5 |
|
Пример 2¶
Предыдущий пример можно переформулировать в хвостовую рекурсивную форму, добавив дополнительный параметр (который должен быть установлен в 1 при первом вызове):
1 2 3 4 5 6 7 |
|
Вызов x:factorial(1, 5)
возвращает 120
.