Чтение онлайн

ЖАНРЫ

Технология XSLT

Валиков Алексей Н.

Шрифт:

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

xsl:key
, который определяет в преобразовании именованный ключ, и функция
key
, которая возвращает множество узлов, идентифицирующихся заданными значениями ключей.

Элемент xsl:key

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

<xsl:key

 name="имя"

 match="паттерн"

 use="выражение"/>

Элемент

верхнего уровня
xsl:key
определяет в преобразовании ключ именем, заданным в значении атрибута
name
, значением которого для каждого узла документа, соответствующего паттерну
match
, будет результат вычисления выражения, заданного в атрибуте
use
. Ни атрибут
use
, ни атрибут
match
не могут содержать переменных.

Пример

В нашем примере элементы

item
идентифицируются значениями своих атрибутов
source
. Для их идентификации мы можем определить ключ с именем
src
следующим образом:

<xsl:key name="src" match="item" use="@source"/>

Следуя строгому определению, данному в спецификации языка, ключом называется тройка вида

(node, name, value)
, где
node
— узел,
name
— имя и
value
— строковое значение ключа. Тогда элементы
xsl:key
, включенные в преобразование, определяют множество всевозможных ключей обрабатываемого документа. Если этому множеству принадлежит ключ, состоящий из узла
x
, имени
у
и значения
z
, говорят, что узел
x
имеет ключ с именем
у
и значением
z
или что ключ
у
узла
x
равен
z
.

Пример

Ключ

src
из предыдущего примера определяет множество, которое состоит из следующих троек:

(<item name="A".../>, 'src', 'a')

(<item name="B".../>, 'src', 'b')

(<item name="C".../>, 'src', 'a')

(<item name="D".../>, 'src', 'c')

...

(<item name="H".../>, 'src', 'a')

В соответствии с нашими определениями мы можем сказать, что элемент

<item source="b" name="B"/>

имеет ключ с именем

"src"
и значением
"b"
или что ключ
"src"
элемента

<item source="a" name="H"/>

равен

"a"
.

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

key
, о которой мы сейчас и поговорим.

Функция key

Ниже приведена синтаксическая конструкция данной функции:

node-set key(string, object)

Итак, элементы

xsl:key
нашего преобразования
определили множество троек
(node, name, value)
. Функция
key(key-name, key-value)
выбирает все узлы x такие, что значение их ключа с именем
key-name
(первым аргументом функции) равно
key-value
(второму аргументу функции).

Пример

Значением выражения

key('src', 'a')
будет множество элементов
item
таких, что значение их ключа
"src"
будет равно
"а"
. Попросту говоря, это будет множество объектов источника
"а"
.

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

Но не следует забывать, что язык XSLT — довольно нетрадиционный язык и с точки зрения синтаксиса, и с точки зрения модели данных. Как следствие, ключи в нем имеют довольно много скрытых нюансов, которые очень полезно знать и понимать. Мы попытаемся как можно более полно раскрыть все эти особенности.

Определение множества ключей

Не представляет особой сложности определение множества ключей в случае, если в определении они идентифицируются строковыми выражениями. Например, в следующем определении

<xsl:key name="src" match="item" use="string(@source)"/>

атрибут

use
показывает, что значением ключа
src
элемента
item
будет значение атрибута
source
. Но что можно сказать о следующем определении:

<xsl:key name="src" match="item" use="@*"/>

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

xsl:key
преобразования, но как именно оно определяется — оставалось доселе загадкой. Восполним этот пробел, дав строгое определение множеству ключей.

Узел

x
обладает ключом с именем
у
и строковым значением
z
тогда и только тогда, когда в преобразовании существует элемент
xsl:key
такой, что одновременно выполняются все нижеперечисленные условия:

□ узел

x
соответствует паттерну, указанному в его атрибуте
match
;

□ значение его атрибута

name
равно имени
y
;

□ результат

u
вычисления выражения, указанного в значении атрибута
use
в контексте текущего множества, состоящего из единственного узла
x
, удовлетворяет одному из следующих условий:

 • 

u
является множеством узлов и
z
равно одному из их строковых значений;

 • 

u
не является множеством узлов и
z
равно его строковому значению.

Без сомнения, определение не из простых. Но как бы мы действовали, если бы физически создавали в памяти множество ключей? Ниже представлен один из возможных алгоритмов:

□ для каждого элемента

xsl:key
найти множество узлов документа, удовлетворяющих его паттерну
match
(множество
X
);

Поделиться с друзьями: