Алексей Валиков - Технология XSLT
Стандартные интерфейсы расширений
Важным дополнением в XSLT 1.1 по сравнению с первой версией языка является определение стандартных интерфейсов расширения для языков IDL, JavaScript/ECMAScript и Java на основе интерфейсов DOM2.
Одна из проблем, с которыми всегда приходится сталкиваться при работе с расширениями, является проблема переносимости. Вследствие того, что интерфейсы привязки к конкретным языкам программирования отдали в первой версии на усмотрение разработчиков процессоров, несовместимость интерфейсов не позволяет гарантировать работоспособность расширений при переходе с одного процессора на другой (даже если речь идет о процессорах одного типа, например, написанных на языке Java процессорах Saxon, Xalan и Oracle XSLT Processor).
Ситуация, действительно, довольно досадная. С одной стороны, и XSLT, и Java являются переносимыми языками, с другой стороны, их сочетание в случае использования расширений оказывается непереносимым даже на Java-платформах. Стандартные интерфейсы, выработанные в XSLT 1.1, по всей вероятности, намного упростят положение вещей — ведь если написанное единожды Java-расширение будет работать на всех Java-платформах, этого уже будет достаточно, для того чтобы смело использовать всю мощь расширений.
Другие изменения
Помимо приведенных выше отличий версии 1.1 от первой версии языка, новый вариант включает в себя также некоторые другие добавления и исправления:
□ добавлена расширенная поддержка пространств имен при преобразовании;
□ добавлена поддержка XML Base;
□ добавлена возможность использования параметров при вызове шаблонов элементом xsl:apply-imports;
□ расширено множество атрибутов элементов XSLT, которые могут содержать шаблоны значений атрибутов;
□ добавлено определение лексикографического порядка (наподобие 'а' < 'b' → true);
□ добавлено сравнение строк без учета регистра символов;
□ добавлены операторы для проверки порядка следования узлов в документе;
□ исправлены обнаруженные ошибки.
Отличия XSLT 2.0 от XSLT 1.1
Прежде чем приступить к описанию отличий второй версии XSLT от версии 1.1 (и, соответственно, 1.0), следует сделать одно существенное замечание. Лицензионные соглашения Консорциума W3 не позволяют раскрывать широкой общественности внутренние материалы рабочих групп W3C до того, как они будут официально опубликованы. Потому, строго говоря, все, что будет ниже сказано о версии 2.0 — это не более чем совокупность гипотез, пожеланий и выводов, сделанных на основе спецификации XSLT 1.1 и требований к XSLT 2.0 и XPath 2.0. Эти документы доступны публично.
Изменения в XPath 2.0
Разрабатываемая версия языка XPath, вследствие интеграции с XQuery, очевидно, претерпит серьезные изменения. Новая спецификация уже сейчас разбита на два документа: документ, описывающий модель данных и документ, описывающий функции и операторы. Поэтому на данный момент сложно делать точный прогноз относительно того, что же получится в итоге. Мы ограничимся перечислением основных требований:
□ поддержка группы XML-стандартов: определение модели в терминах XML Information Set, выделение общего синтаксиса и семантики с XQuery 1.0;
□ переопределение операторов сравнения на множествах;
□ определение операторов пересечения и разности множеств;
□ расширение множества агрегатных функций (наподобие sum, count, min, max — функций, работающих на множествах);
□ возможность использования выражений, возвращающих множества узлов в качестве шагов выборки, например /a/(b|c)/d вместо /а/b/d | /a/c/d;
□ введение оператора аналогичного оператору ? в Java и С (выражение a ? b : с, где а имеет булевый тип, возвращает b, если a — "истина" и с, если a — "ложь");
□ дополнительные строковые функции как-то: замена подстроки, выравнивание, изменение регистра символов;
□ поддержка регулярных выражений;
□ поддержка примитивных типов XML Schema;
□ использование информации о структуре документа, определенной в его схеме;
□ поддержка экспоненциальной нотации чисел (наподобие 2Е10 = 1024);
□ поддержка функций приведения и преобразования (аналог CAST и CONVERT из SQL).
Выбор шаблонов для элементов пространства имен, определенного по умолчанию
Одним из значительных неудобств первой версии XSLT была невозможность сменить пространство имен, определенное по умолчанию для паттернов. То есть, если шаблон будет определен как
<xsl:template match="foo">
...
</xsl:template>
то обрабатывать он будет только те элементы foo, которые принадлежат нулевому пространству имен. Для элемента
<bar:foo xmlns:bar="urn:bar-namespace"/>
придется писать шаблон вида
<xsl:template match="ns:foo" xmlns:ns="urn:bar-namespace">
...
</xsl:template>
В случае целого документа принадлежащего ненулевому пространству имен, определения подобного рода могут оказаться слишком громоздкими. Решение этой проблемы может быть очень простым и элегантным.
Листинг 12.8. Изменение пространства имен для паттерна<xsl:stylesheet
version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="urn:bar-namespace">
<xsl:template match="foo">
...
</xsl:template>
</xsl:stylesheet>
В элементе xsl:stylesheet пространство имен с URI "urn:bar-namespace" определяется как пространство имен по умолчанию и паттерн foo соответствует элементу с локальной частью имени "foo" и URI пространства имен "urn:bar-namespace".
Средства для форматирования даты и времени
В первых версиях XSLT элемент xsl:decimal-format и функция format-number обеспечивали форматирование чисел при их текстовом отображении. К сожалению, подобных инструментов для форматирования даты предусмотрено не было.
Поскольку связка элемента, определяющего именованный формат и функции, выполняющей форматирование, оказалась очень удачной, по всей вероятности, подобную схему мы будем наблюдать и в версии 2.0. Скорее всего, связка для форматирования даты и времени будет состоять из элемента xsl:date-format и функции format-date.
Функции id и key на внешних документах
В XSLT 1.1 функции id и key возвращают множества узлов документа, который содержит текущий узел преобразования. То есть для того, чтобы использовать ключи или уникальные идентификаторы для выбора узлов внешнего документа, необходимо сначала сменить контекст, например:
<xsl:for-each select="document('ext.xml')">
<xsl:copy-of select="key('name', 'value')"/>
</xsl:for-each>
Требования ко второй версии XSLT предполагают упрощение работы с ключами и уникальными идентификаторами на внешних документах.
Включение неразбираемых внешних сущностей в виде текста
В первых версиях XSLT отсутствовала возможность включения внешних сущностей, не разбирая их как XML-документы. Без помощи расширений было невозможно включить в выходящий документ простой внешний текстовый файл. Между тем, вполне подходящим решением была бы функция типа unparsed-entity, которая по данному URI возвращала бы содержимое ресурса в виде строки. Естественно, при этом необходимо учитывать кодировку внешней сущности и Unicode-символы, которые не могут присутствовать в XML (например, управляющие символы).
Использование именованных сущностей вместо кодов символов
Это требование связано с желанием пользователей видеть в выходящем документе вместо сущности   ее более привычный вариант . В настоящее время приходится прибегать ко всяким хитростям вроде
<xsl:text disable-output-escaping="yes">&nbsp;</xsl:text>
совсем не гарантирующим, кстати, что в выходящем файле окажется именно .
В самом преобразовании сущности можно определять в DTD-заголовке следующим образом:
<!DOCTYPE xsl:stylesheet [
<!ENTITY nbsp "&#хА0;">
]>
<xsl:stylesheet ... >
...
</xsl:stylesheet>
Однако на выходящий документ эти определения никоим образом не сказываются.
Обращение ссылок по ID/IDREF
Функция id позволяет отыскать в документе элементы по заданным значениями ID-атрибутов. Это особенно полезно при работе с IDREF-атрибутами, которые ссылаются на ID-атрибуты: можно с легкостью выбрать элементы, на которые ссылается текущий элемент. Новым требованием к XSLT 2.0 является возможность "обращать" такого рода ссылки — то есть находить элементы, которые ссылаются на данный элемент (включают определенные значения в свои IDREF-атрибуты).