Технология XSLT — страница 33 из 66

По большому счету, мы не можем контролировать процесс преобразования. Процессор может сам выбирать, как и в какой последовательности он будет выполнять те или иные шаблоны — таковы особенности декларативного программирования. Вместе с тем мы все-таки можем получить кое-какую информацию о ходе преобразования, используя механизм, называемый в XSLT сообщениями.

Элемент xsl:message

Синтаксис этого элемента дан ниже:

 terminate="yes" | "no">

Элемент

xsl:message
указывает процессору на то, что он должен вывести сообщение, которое является результатом обработки шаблона, содержащегося в этом элементе. Механизм вывода сообщения зависит от реализации того или иного процессора и может быть различным — от вывода текста сообщения на экран до вызова внешнего модуля для обработки сообщения.

Пример

Иногда в процессе отладки преобразования бывает полезно выводить сообщения о том, какой элемент обрабатывается в данный момент.

Листинг 8.5. Входящий документ

Листинг 8.6. Преобразование

 version="1.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">


Processing element 

 which has a parent element 

.


Листинг 8.7. Выходящий документ

Листинг 8.8. Сообщения процессора

Processing element a.

Processing element b which has a parent element a.

Processing element с which has a parent element b.

Processing element d which has a parent element c.

Атрибут

terminate
указывает на то, должен ли процессор прекратить дальнейшую обработку документа или нет. Значением этого атрибута по умолчанию является
"no"
, что означает, что процессор должен просто вывести сообщения и продолжать дальнейшее выполнение шаблона. Если же в
xsl:message
указано
terminate="yes"
, то процессор, выведя сообщение, прервет обработку. Этот прием может использоваться, например, для того, чтобы проверять входящие документы на соответствие определенной схеме.

Пример

При помощи

xsl:message
мы можем запретить обработку документов, которые не имеют в корне элемент с именем
"html"
в любом регистре символов.

Листинг 8.9. Шаблон преобразования

Document has no root HTML element.

Если мы будем обрабатывать документ вида

обработка не будет прервана, в то время как преобразование документа

будет прервано сообщением:

Document has no root HTML element:

Processing terminated using xsl:message

Сортировка

При преобразовании документа элементами

xsl:for-each
и
xsl:apply-templates
, выбранные узлы по умолчанию обрабатываются в порядке просмотра документа, который зависит от выражения, использованного в атрибуте
select
этих элементов. XSLT позволяет изменять этот порядок посредством использования механизма сортировки.

Элементы

xsl:for-each
и
xsl:apply-templates
могут содержать один или несколько элементов
xsl:sort
, которые позволяют предварительно сортировать обрабатываемое множество узлов.

Элемент xsl:sort

Синтаксис этого элемента определяется в XSLT как:

select = "выражение"

 lang = "язык"

 data-type = "text" | "number" | "имя"

 order = "ascending" | "descending"

 case-order = "upper-first" | "lower-first" />

В случае если

xsl:for-each
и
xsl:apply-templates
содержат элементы
xsl:sort
, обработка множества узлов должна производиться не в порядке просмотра документа, а в порядке, который определяется ключами, вычисленными при помощи
xsl:sort
. Первый элемент
xsl:sort
, присутствующий в родительском элементе, определяет первичный ключ сортировки, второй элемент — вторичный ключ, и так далее.

Элемент

xsl:sort
обладает атрибутом
select
, значением которого является выражение, называемое также ключевым выражением. Это выражение вычисляется для каждого узла обрабатываемого множества, преобразуется в строку и затем используется как значение ключа при сортировке. По умолчанию значением этого атрибута является
"."
, что означает, что в качестве значения ключа для каждого узла используется его строковое значение.

После этих вычислений узлы обрабатываемого множества сортируются по полученным строковым значениям своих ключей и обрабатываются в новом порядке. Если ключи некоторых узлов совпадают, они могут быть в дальнейшем отсортированы вторичными и так далее ключами.

Элемент

xsl:sort
может иметь следующие необязательные атрибуты, которые указывают некоторые параметры сортировки.

□ Атрибут

order
определяет порядок, в котором узлы должны сортироваться по своим ключам. Этот атрибут может принимать только два значения —
"ascending"
, указывающее на восходящий порядок сортировки, и
"descending"
, указывающее на нисходящий порядок. Значением по умолчанию является
"ascending"
, то есть восходящий порядок.

□ Атрибут

lang
определяет язык ключей сортировки. Дело в том, что в разных языках символы алфавита могут иметь различный порядок, что, соответственно, должно учитываться при сортировке. Атрибут
lang
в XSLT может иметь те же самые значения, что и атрибут
xml: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
по умолчанию зависит от процессора и языка сортировки. В большинстве случаев заглавные буквы идут первыми.

Как можно видеть, элемент

xsl:sort
определяет сортировку достаточно гибко, но вместе с тем не следует забывать, что эти возможности могут быть реализованы в процессорах далеко не полностью. Поэтому одна и та же сортировка может быть выполнена в разных процессорах по-разному.

Приведем простой пример сортировки имен и фамилий.

Рассмотрим пример.

Листинг 8.10. Входящий документ

William

Gibson

William

Blake

John

Fowles

Отсортируем этот список сначала по именам в убывающем, а затем по фамилиям в возрастающем порядке.

Листинг 8.12. Выходящий документ

William

Blake

William

Gibson

John

Fowles

К сожалению, сортировкой нельзя управлять динамически. Все атрибуты элемента

xsl:sort
должны обладать фиксированными значениями.

Псевдонимы пространств имен