Несмотря на то, что произведенные нами манипуляции чрезвычайно просты (и настолько же эффективны), процессор вряд ли в общем случае сможет сделать что-либо подобное сам, и потому очень важной является возможность явным образом выделять в XSLT-преобразованиях ключевые свойства множеств узлов.
В этом разделе мы будем рассматривать две конструкции, позволяющие манипулировать множествами узлов посредством ключей — это элемент xsl:key
, который определяет в преобразовании именованный ключ, и функция key
, которая возвращает множество узлов, идентифицирующихся заданными значениями ключей.
Синтаксис элемента несложен:
name=" имя "
match=" паттерн "
use=" выражение "/>
Элемент верхнего уровня xsl:key
определяет в преобразовании ключ именем, заданным в значении атрибута name
, значением которого для каждого узла документа, соответствующего паттерну match
, будет результат вычисления выражения, заданного в атрибуте use
. Ни атрибут use
, ни атрибут match
не могут содержать переменных.
Пример
В нашем примере элементы item
идентифицируются значениями своих атрибутов source
. Для их идентификации мы можем определить ключ с именем src
следующим образом:
Следуя строгому определению, данному в спецификации языка, ключом называется тройка вида ( 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')
В соответствии с нашими определениями мы можем сказать, что элемент
имеет ключ с именем "src"
и значением "b"
или что ключ "src"
элемента
равен "a"
.
Для того чтобы обращаться к множествам узлов по значениям их ключей, в XSLT существует функция 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 — довольно нетрадиционный язык и с точки зрения синтаксиса, и с точки зрения модели данных. Как следствие, ключи в нем имеют довольно много скрытых нюансов, которые очень полезно знать и понимать. Мы попытаемся как можно более полно раскрыть все эти особенности.
Определение множества ключей
Не представляет особой сложности определение множества ключей в случае, если в определении они идентифицируются строковыми выражениями. Например, в следующем определении
атрибут use
показывает, что значением ключа src
элемента item
будет значение атрибута source
. Но что можно сказать о следующем определении:
Очевидно, это уже гораздо более сложный, но, тем не менее, вполне реальный случай, не вписывающийся в определения, которые давались до сих пор. Мы говорили лишь о том, что множество ключей определяется элементами xsl:key
преобразования, но как именно оно определяется — оставалось доселе загадкой. Восполним этот пробел, дав строгое определение множеству ключей.
Читать дальше