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

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);

□ для каждого из найденных узлов (xX) вычислить значение выражения атрибута use (значение u(x));

□ если u(x) является множеством узлов (назовем его Uх), то для каждого uxiUх создать ключ (x, n, string(uxi)), где n — имя ключа (значение атрибута name элемента xsl:key);

□ если u(x) является объектом другого типа (назовем его ux), создать ключ (x, n, string(ux)).

Пример

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

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

Имена всех ключей будут одинаковы и равны 'src'. Множество x узлов, удовлетворяющих паттерну item, будет содержать все элементы item обрабатываемого документа. Значением выражения, заданного в атрибуте use, будет множество всех узлов атрибутов каждого из элементов item. Таким образом, множество узлов будет иметь следующий вид:

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

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

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

(<item name='В'.../>, 'src', 'В')

(<item name='С'.../>, 'src', 'а')

(<item name='С'.../>, 'src', 'С')

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

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

...

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

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

В итоге функция key('src', 'a') будет возвращать объекты с именами A, C и H, а функция key('src', 'A') — единственный объект с именем A (поскольку ни у какого другого элемента item нет атрибута со значением 'A').

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

Использование нескольких ключей в одном преобразовании

Вы читаете Технология XSLT
Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату