В случае, когда к узлам в преобразовании нужно обращаться по значениям различных свойств, можно определить несколько ключей — каждый со своим именем. Например, если мы хотим в одном случае обращаться к объектам, принадлежащим одному источнику, а во втором — к объектам с определенными именами, мы можем определить в документе два ключа — один с именем src
, второй — с именем name
:
<xsl:key name='src' match='item' use='@source'/>
<xsl:key name='name' match='item' use='@name'/>
Множество ключей, созданных этими двумя определениями, будет выглядеть следующим образом:
(<
(<
(<
(<
(<
(<
(<
(<
...
(<
(<
В этом случае функция key('src', 'а')
возвратит объекты с именами A
, C
и H
, а функция key('name', 'а')
— объект с именем А
.
Имя ключа является расширенным именем. Оно может иметь объявленный префикс пространства имен, например
<xsl:key
name='data:src'
match='item'
use='@source'
xmlns:data='urn:user-data'/>
В этом случае функция key(key-name, key-value)
будет возвращать узлы, значение ключа с расширенным именем key-name
которых равно key-value
. Совпадение расширенных имен определяется как обычно — по совпадению локальных частей и URI пространств имен.
Использование нескольких определений одного ключа
Процессор должен учитывать все определения ключей данного преобразования — даже если некоторые из них находятся во включенных или импортированных модулях. Порядок импорта элементов xsl:key
не имеет значения: дело в том, что определения ключей с одинаковыми именами для одних и тех же узлов, но с разными значениями ключа не переопределяют, а дополняют друг друга.
Предположим, что в нашем документе имеется несколько элементов item
, в которых не указано значение атрибута source
, но по умолчанию мы будем причислять их к источнику а
. Соответствующие ключи будут определяться следующим образом:
<xsl:key name='src' match='item[@source]' use='@source'/>
<xsl:key name='src' match='item[not(@source)]' use=''a''/>
To есть для тех элементов item
, у которых есть атрибут source
, значением ключа будет значение этого атрибута, для тех же элементов, у которых атрибута source
нет, его значением будет 'а'
.
Для входящего документа вида
<items>
<item source='a' name='A'/>
<item source='b' name='B'/>
<item source='a' name='C'/>
<item source='c' name='D'/>
...
<item source='a' name='H'/>
<item name='I'/>
<item name='J'/>
<item name='K'/>
</items>
соответствующее множество ключей будет определяться следующим образом:
(<
(<
(<
(<
...
(<
(<
(<
(<
Функция key('src', 'a')
возвратит объекты с именами A
, C
, H
, I
, J
и K
.
То, что одни и те же узлы могут иметь разные значения одного ключа, является также очень удобным свойством. Например, два определения ключей, приведенные выше, можно дополнить третьим:
<xsl:key name='src' match='item[not(@source)]' use=''#default''/>
Это определение позволит по значению '#default'
обращаться к объектам, принадлежащим источнику по умолчанию.
Использование множеств узлов в функции
Функция key
принимает на вход два аргумента: первым аргументом является строка, задающая имя ключа, в то время как вторым аргументом может быть объект любого типа. В том случае, если аргумент
в функции key(
является множеством узлов, функция key
возвратит все узлы, имеющие ключ
со значением, равным хотя бы одному из строковых значений узла множества
.
Предположим, что источники объектов будут сгруппированы следующим образом:
<sources>
<source name='a'/>