После этих вычислений узлы обрабатываемого множества сортируются по полученным строковым значениям своих ключей и обрабатываются в новом порядке. Если ключи некоторых узлов совпадают, они могут быть в дальнейшем отсортированы вторичными и так далее ключами.
Элемент xsclass="underline" sort может иметь следующие необязательные атрибуты, которые указывают некоторые параметры сортировки.
□ Атрибут order определяет порядок, в котором узлы должны сортироваться по своим ключам. Этот атрибут может принимать только два значения — "ascending", указывающее на восходящий порядок сортировки, и "descending", указывающее на нисходящий порядок. Значением по умолчанию является "ascending", то есть восходящий порядок.
□ Атрибут lang определяет язык ключей сортировки. Дело в том, что в разных языках символы алфавита могут иметь различный порядок, что, соответственно, должно учитываться при сортировке. Атрибут lang в XSLT может иметь те же самые значения, что и атрибут xmclass="underline" lang (например: "en", "en-us", "ru" и т.д.). Если значение этого атрибута не определено, процессор может либо определять язык исходя из параметров системы, либо сортировать строки исходя из порядка кодов символов Unicode.
□ Атрибут 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 по умолчанию зависит от процессора и языка сортировки. В большинстве случаев заглавные буквы идут первыми.
Как можно видеть, элемент xsclass="underline" sort определяет сортировку достаточно гибко, но вместе с тем не следует забывать, что эти возможности могут быть реализованы в процессорах далеко не полностью. Поэтому одна и та же сортировка может быть выполнена в разных процессорах по-разному.
Приведем простой пример сортировки имен и фамилий.
Рассмотрим пример.
<list>
<person>
<name>William</name>
<surname>Gibson</surname>
</person>
<person>
<name>William</name>
<surname>Blake</surname>
</person>
<person>
<name>John</name>
<surname>Fowles</surname>
</person>
</list>
Отсортируем этот список сначала по именам в убывающем, а затем по фамилиям в возрастающем порядке.
<xsclass="underline" template match="list">
<xsclass="underline" copy>
<xsclass="underline" for-each select="person">
<xsclass="underline" sort select="name" order="descending"/>
<xsclass="underline" sort select="surname"/>
<xsclass="underline" copy-of select="."/>
</xsclass="underline" for-each>
</xsclass="underline" copy>
</xsclass="underline" template>
<list>
<person>
<name>William</name>
<surname>Blake</surname>
</person>
<person>
<name>William</name>
<surname>Gibson</surname>
</person>
<person>
<name>John</name>
<surname>Fowles</surname>
</person>
</list>
К сожалению, сортировкой нельзя управлять динамически. Все атрибуты элемента xsclass="underline" sort должны обладать фиксированными значениями.
Псевдонимы пространств имен
Любопытным фактом является то, что XML-документ, являющийся результатом выполнения XSLT-преобразования, может и сам быть XSLT- преобразованием. Иными словами, преобразования могут генерироваться другими преобразованиями. В некоторых случаях такая возможность будет очень полезна, например, входящий XML-документ может описывать преобразование, которое нужно сгенерировать.
<transform>
<remove select="a"/>
<replace select="b" with="B"/>
<replace select="c" with="C"/>
</transform>
Приведенный выше документ описывает преобразование, которое должно удалять из входящего документа элементы а, а элементы b и c заменять элементами B и C соответственно. Такое преобразование может выглядеть следующим образом.
<xsclass="underline" stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsclass="underline" template match="a"/>
<xsclass="underline" template match="b">
<xsclass="underline" element name="B">
<xsclass="underline" apply-templates/>
</xsclass="underline" element>
</xsclass="underline" template>
<xsclass="underline" template match="c">
<xsclass="underline" element name="C">
<xsclass="underline" apply-templates/>
</xsclass="underline" element>