□ Атрибут data-type
определяет тип данных, который несут строковые значения ключей. Техническая рекомендация XSLT разрешает этому атрибуту иметь следующие значения:
• "text"
— ключи должны быть отсортированы в лексикографическом порядке исходя из языка, определенного атрибутом lang
или параметрами системы;
• "number"
— ключи должны сравниваться в численном виде. Если строковое значение ключа не является числом, оно будет преобразовано к не-числу ( NaN
), и, поскольку нечисловые значения неупорядочены, соответствующий узел может появиться в отсортированном множестве где угодно;
• " имя "
— в целях расширяемости XSLT также позволяет указывать в качестве типа данных произвольное имя. В этом случае реализация сортировки полностью зависит от процессора;
• значением атрибута data-type
по умолчанию является "text"
.
□ Атрибут case-order
указывает на порядок сортировки символов разных регистров. Значениями этого атрибута могут быть "upper-first"
, что означает, что заглавные символы должны идти первыми, или "lower-first"
, что означает, что первыми должны быть строчные символы. К примеру, строки "ночь"
, "Улица"
, "фонарь"
, "Аптека"
, "НОЧЬ"
, "Фонарь"
при использовании case-order="upper-first"
будут иметь порядок "Аптека"
, "НОЧЬ"
, "ночь"
, "Фонарь"
, "фонарь"
, "улица"
. При использовании case-order="lower-first"
те же строки будут идти в порядке "Аптека"
, "ночь"
, "НОЧЬ"
, "фонарь"
, "Фонарь"
, "улица"
. Значение case-order
по умолчанию зависит от процессора и языка сортировки. В большинстве случаев заглавные буквы идут первыми.
Как можно видеть, элемент xsl:sort
определяет сортировку достаточно гибко, но вместе с тем не следует забывать, что эти возможности могут быть реализованы в процессорах далеко не полностью. Поэтому одна и та же сортировка может быть выполнена в разных процессорах по-разному.
Приведем простой пример сортировки имен и фамилий.
Рассмотрим пример.
Листинг 8.10. Входящий документ
William
Gibson
William
Blake
John
Fowles
Отсортируем этот список сначала по именам в убывающем, а затем по фамилиям в возрастающем порядке.
Листинг 8.12. Выходящий документ
William
Blake
William
Gibson
John
Fowles
К сожалению, сортировкой нельзя управлять динамически. Все атрибуты элемента xsl:sort
должны обладать фиксированными значениями.
Псевдонимы пространств имен
Любопытным фактом является то, что XML-документ, являющийся результатом выполнения XSLT-преобразования, может и сам быть XSLT- преобразованием. Иными словами, преобразования могут генерироваться другими преобразованиями. В некоторых случаях такая возможность будет очень полезна, например, входящий XML-документ может описывать преобразование, которое нужно сгенерировать.
Листинг 8.13. XML-документ, описывающий требуемое преобразование
Приведенный выше документ описывает преобразование, которое должно удалять из входящего документа элементы а
, а элементы b
и c
заменять элементами B
и C
соответственно. Такое преобразование может выглядеть следующим образом.
Листинг 8.14. Преобразование
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
Преобразование, генерирующее такой код, не представляет особой сложности. Например, шаблон для обработки элемента replace может иметь следующий вид:
Шаблон этот выглядит очень громоздко, потому что мы не могли просто включить в него создаваемое правило: поскольку мы создаем элементы в пространстве имен XSLT, находясь в шаблоне, они воспринимались бы не как генерируемые, а как принадлежащие генерирующему преобразованию. Очевидно, что шаблон вида
был бы некорректен. По этой причине нам пришлось генерировать все инструкции при помощи xsl:element
и xsl:attribute
, что сделало шаблон громоздким и малопонятным.
Если внимательно рассмотреть проблему, то окажется, что она состоит в том, что мы хотим в преобразовании использовать элементы одного пространства имен так, как если бы они относились к другому пространству.
К счастью, XSLT предоставляет легкий и удобный способ для решения такого рода задачи: пространству имен можно назначить псевдоним при помощи элемента xsl:namespace-alias
.
Читать дальше