Строковый аргумент этой функции представляет расширенное имя функции, он должен соответствовать продукции
QName
, то есть иметь вид
имя
или
префикс:имя
. В первом случае
function-available
проверяет, реализована ли в данном процессоре стандартная функция с таким именем, например
function-available('concat')
скорее всего, возвратит
true
.
В случае, если аргумент
function-available
имеет вид
префикс:имя
,
функция
function-available
проверяет доступность указанной функции расширения. Например, для того, чтобы проверить, может ли в данном контексте быть вызвана функция
rot:X
, необходимо вычислить выражение
function-available('rot:X')
В данном случае
true
будет означать, что функция
rot:X
может быть вызвана,
false
— что функция в силу каких-то причин недоступна.
Функция
function-available
может помочь в создании преобразований, которые используют расширения, но при этом в некоторой степени сохраняют переносимость между различными процессорами. Достаточно написать несколько вариантов вызова функции расширения для каждого из процессоров, на которых преобразование должно работать, а затем использовать вариант с доступной данному процессору функцией расширения.
Пример
Для того чтобы обеспечить работоспособность расширения, реализованного классом
de.fzi.xslt.rot
в наиболее распространенных XSLT-процессорах, написанных на Java (как-то: Saxon, Xalan и Oracle XSLT Processor), прежде всего необходимо объявить соответствующие пространства имен:
будет доступна при обработке, она будет использована процессором для создания атрибутов элемента
line
. В противном случае, процессор прервет выполнение преобразования и выведет указанное в элементе
xsl:message
сообщение.
Нельзя не согласиться с тем, что приведенный выше способ не отличается элегантностью. Реализовывать свой вариант для каждого существующего процессора может быть довольно трудоемкой задачей — но такова уж плата за возможности расширений.
Функция расширения nodeset
Одной из самых полезных функций расширения, которая, как правило, уже штатно реализована во многих процессорах (то есть, не требует дополнительного программирования) является функция
nodeset
. Эта функция позволяет в обход прямого запрета спецификации конвертировать результирующий фрагмент дерева во множество узлов.
Предположим, что мы создаем в переменной
rtf
результирующий фрагмент дерева следующего вида:
<xsl:variable name="rtf">
<item>1</item>
<item>2</item>
<item>3</item>
</xsl:variable>
При попытке вычислить выражение вида
$rtf/item[2]
процессор в соответствии со спецификацией должен вывести ошибку, поскольку в этом фильтрующем выражении (см. продукцию
[XP20] FilterExpr
) переменная
rtf
должна содержать множество узлов, а не фрагмент дерева.
Текущая спецификация языка XPath совершенно явно говорит о том, что ни один тип данных не может быть преобразован во множество узлов. Функция
nodeset
действует в обход этого запрещения: она принимает на вход результирующий фрагмент дерева и возвращает множество, состоящее из корневого узла этого фрагмента.
В разных процессорах эта функция имеет различный синтаксис: она может носить имя