Несмотря на то, что произведенные нами манипуляции чрезвычайно просты (и настолько же эффективны), процессор вряд ли в общем случае сможет сделать что-либо подобное сам, и потому очень важной является возможность явным образом выделять в 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преобразования, но как именно оно определяется — оставалось доселе загадкой. Восполним этот пробел, дав строгое определение множеству ключей.
Читать дальше