Естественно, семантика элементов расширения не ограничивается простым копированием в выходящий документ заданных значений. Элементы расширения могут выполнять гораздо более сложные функции, ограниченные, пожалуй, лишь только воображением разработчика. При этом элементы расширения на удивление удачно вписываются в структуру самого преобразования, ведь принцип их использования не сильно отличается от принципа использования самих элементов XSLT.
Функция element-available
boolean element-available(string)
Функция
element-available
совершенно аналогична функции
function-available
: она служит для проверки доступности в преобразовании того или иного элемента. Строковый параметр
element-available
задает расширенное имя элемента; функция возвращает
true
, если элемент с таким именем доступен,
false
— если нет.
Пример
Предположим, что преобразование, созданное нами для процессора Xalan с использованием элемента расширения
ext:date
, будет выполняться на каком-либо другом процессоре. В этом случае велика вероятность того, что вследствие несовместимости механизмов расширений это преобразование завершится ошибкой — "чужой" процессор просто не сможет выполнить элемент
This page was generated at <ext:date pattern="HH:mm"/> on <ext:date pattern="dd/MM/yyyy"/>.
</xsl:if>
</result>
</xsl:template>
</xsl:stylesheet>
Элемент xsl:fallback
Другим способом обработки исключительных ситуаций, связанных с невозможностью выполнить тот или иной элемент преобразования, является использование элемента
xsl:fallback
. Синтаксическая конструкция этого элемента следующая:
<xsl:fallback>
<!-- Содержимое: шаблон -->
</xsl:fallback>
Элемент
xsl:fallback
включается в "критическую" инструкцию, то есть в элемент, который может быть неизвестен процессору. В случае, если критическая инструкция отрабатывается нормально, содержимое
xsl:fallback
попросту игнорируется. Иначе, если процессор в силу некоторых причин не может выполнить критическую инструкцию, вместо нее он будет выполнять содержимое дочернего элемента
xsl:fallback
.
Пример
На тот случай, если процессор не сможет выполнить наш элемент расширения
ext:date
, мы можем "подстраховать" его следующим образом:
<ext:date pattern="HH:mm">
<xsl:fallback>unknown time</xsl:fallback>
</ext:date>
В этом случае шаблон
<xsl:template match="/">
<!-- ... – ->
This page was generated at <ext:date pattern="HH:yy">
<xsl:fallback>unknown time</xsl:fallback>
</ext:date>.
</xsl:template>
в случае невозможности выполнить
ext:date
выведет
This page was generated at unknown time.
Заметим, что
xsl:fallback
применим не только для обработки исключительных ситуаций, связанных с элементами расширения. Наборы доступных процессору элементов XSLT будут также меняться от версии к версии, и
xsl:fallback
вполне пригодится для обеспечения обратной совместимости. Например, если в версии XSLT 2.0 будет определен элемент
xsl:for-each-group
, то
xsl:fallback
можно использовать при создании альтернативного варианта для процессоров, которые еще не поддерживают новую версию:
Функции и элементы расширения с лихвой восполняют ограниченность языков XSLT и XPath, предоставляя возможности обычных императивных языков там, где они необходимы. Между тем, как показывает практика, задачи, которые приходится решать при помощи расширений, как правило, совершенно стандартны — например, разобранная выше функция nodeset, так или иначе реализована почти во всех XSLT-процессорах.
Инициатива EXSLT была порождена естественным желанием разработчиков иметь в своих XSLT-преобразованиях стандартные расширения и не дублировать усилия по решению общих проблем. В рамках EXSLT создаются стандартные библиотеки расширений XSLT для различных процессоров. Кроме того, EXSLT активно поддерживается многими разработчиками XSLT-процессоров с тем, чтобы обеспечить переносимость преобразований, использующих EXSLT-расширения.