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

Элемент xsl:for-each

Конструкция этого элемента такова:

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

Элемент

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

Пример

Мы можем использовать

xsl:for-each
для того, чтобы создать список гипертекстовых ссылок для документа вида.

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

I'm just a simple page...

  Please visit this link.

  Or this one.

  Or visit this site.

  Or click here.

Будем считать, что в этом документе элементы гипертекстовых ссылок а являются потомками элемента

body
, который находится в элементе
html
.

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

Листинг 7.26. Результат преобразования

http://www.aaa.com

http://www.bbb.com

http://www.ccc.com

http://www.ddd.com

Элемент

xsl:for-each
изменяет контекст преобразования. Множество узлов, возвращаемое выражением в атрибуте
select
, становится текущим множеством узлов, а узел, шаблон для которого выполняется в данный момент, становится текущим узлом.

Как мы знаем, множества узлов в XSLT не имеют внутреннего порядка. Однако, обработка узлов в

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

Глава 8Дополнительные элементы и функции языка XSLT

Дополнительные элементы и функции

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

К дополнительным элементам XSLT мы отнесем следующие:

xsl:preserve-space
и
xsl:strip-space
— работа с пробельными символами;

xsl:message
— сообщения процессора;

xsl:sort
— сортировка множеств перед обработкой;

xsl:namespace-alias
— определение псевдонимов пространств имен;

xsl:key
— определение ключей;

xsl:number
— нумерация;

xsl:decimal-format
— определение десятичного формата;

xsl:output
— контроль сериализации.

В XSLT также определяются дополнительные функции, расширяющие базовую библиотеку функций XPath:

key
— использование ключей;

format-number
— форматирование чисел;

document
— обращение к внешним документам;

current
— обращение к текущему узлу преобразования;

unparsed-entity-uri
— получение URI неразбираемой сущности по ее имени;

generate-id
— генерация уникального идентификатора узла документа;

system-property
— получение информации о свойствах системы, окружения.

Обработка пробельных символов

В XSLT выделяются четыре пробельных символа, обработка которых несколько отличается от обработки других символов. Их Unicode-коды и описания сведены в табл. 8.1.


Таблица 8.1. Unicode-коды пробельных символов

Unicode-кодыОписание
ДесятичныйШестнадцатеричный
#9
#x9
Горизонтальная табуляция
#10
#xA
Перевод строки
#13
#xD
Возврат каретки
#32
#x20
Пробел

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

Пример

Рассмотрим шаблон преобразования, содержащий пробельные символы ("

" обозначает пробел, а "
" — перевод строки).

Листинг 8.1. Шаблон преобразования с пробельными символами

□□□

□□□¶

□□□□□□□□□

□□□□□□¶

□□□□□□□□□

Поскольку текстовые узлы этого шаблона содержат только пробельные символы, они будут удалены из дерева преобразования, и результат будет иметь вид:

Вообще, текстовый узел будет сохранен при выполнении хотя бы одного из следующих условий.

□ Он содержит хотя бы один непробельный символ.

□ Он принадлежит элементу, в котором сохранение пробельных символов задано средствами XML, а именно атрибутом

xml:space
со значением
preserve
.

□ Он принадлежит элементу, имя которого включено во множество имен элементов, для которых нужно сохранять пробельные символы.

Во всех остальных случаях текстовый узел будет удален.

Продемонстрируем все три случая сохранения текстового узла на примерах.

Первый случай довольно прост. Шаблон

□□

создаст в выходящем документе фрагмент

<а/>

безо всяких пробельных символов, в то время как шаблон

□□|

создаст фрагмент вида

□□|

Различие двух этих шаблонов в том, что в первом текстовые узлы содержат текст "

¶ ¶ □□
" и "
¶ ¶ 
" соответственно, а во втором — "
¶ ¶ □□|
" и "
| ¶ ¶
". Текстовые узлы второго шаблона не будут удалены, поскольку они содержат непробельные символы (символы "
|
").

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

xml:space
со значением
"preserve"
, обрабатывающее программное обеспечение должно сохранять в нем и в его потомках пробельные символы. Единственным исключением из этого правила может быть опять же атрибут
xml:space
, заданный в элементе-потомке со значением
"default"
.

Пример

Шаблон

□□<а>¶

□□□□

□□□□□□

□□□□□□□□

□□□□□□¶

□□□□

□□

создаст в выходящем документе фрагмент вида:

Если же шаблон будет определен в виде:

□□<а xml:space="preserve">¶

□□□□

□□□□□□

□□□□□□□□

□□□□□□¶

□□□□

□□¶

то в выходящем фрагменте в элементах

а
и
b
пробельные символы будут сохранены, а в элементах
с
и
d
— удалены:

<а xml:space="preserve">¶

□□□□

□□□□□□

□□□□

□□

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

Для преобразований сохраняющее множество состоит из единственного элемента

xsl:text
, то есть единственный элемент в преобразовании, для которого пробельные текстовые узлы не будут удаляться, — это элемент
xsl:text
. Поэтому его часто используют для вывода в выходящем документе пробельных символов.

Для входящих документов сохраняющее множество состоит из имен всех элементов. То есть по умолчанию преобразования сохраняют все пробельные текстовые узлы. Для изменения сохраняющего множества элементов входящего документа используются элементы

xsl:preserve-space
и
xsl:strip-space
.

Элементы xsl:preserve-space и xsl:strip-space

Синтаксические конструкции этих элементов очень похожи:

elements="токены"/>


elements="токены"/>

Элемент

xsl:preserve-space
добавляет, a
xsl:strip-space
удаляет имя элемента из сохраняющего множества входящего документа.

Пример

Предположим, нам нужно сохранять пробельные символы во всех элементах

d
и удалять их в элементах
с
. Тогда в преобразовании достаточно указать

Вообще, обязательные атрибуты elements элементов

xsl:strip-space
и
xsl:preserve-space
содержат не сами имена элементов, а так называемые проверки имен. Проверка имени имеет три варианта синтаксиса.

□ Синтаксис

"*"
используется для выбора произвольных имен. Ей будут соответствовать любые имена элементов.

□ Синтаксис

"имя"
используется для выбора элементов с заданным именем. К примеру, проверке имени
"d"
будут соответствовать все элементы с именем "
d
".

□ Синтаксис

"префикс:*"
используется для выбора всех элементов в данном пространстве имен. К примеру, если в документе определен префикс пространства имен
upr
в виде атрибута
xmlns:upr="http://www.upr.com"
, проверке имени
"upr:*"
будут соответствовать все элементы пространства имен, определяемого идентификатором
"http://www.upr.com"
.

Пример

Предположим, что нам необходимо сохранить пробельные символы в элементе с именем

с
и удалить их в элементе
e
и элементах, принадлежащих пространству имен, определяемому идентификатором "
urn:d
".

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

<а xmlns:d="urn:d">¶

□□

□□□□

□□□□□□¶

□□□□¶

□□¶

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

 version="1.0"

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



  xmlns:t="urn:d"/>


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

□□

□□□□□□

□□□□¶

Сообщения процессора