Множество ключей, созданных этими двумя определениями, будет выглядеть следующим образом:
(<item name="А".../>, 'src', 'а')
(<item name="А".../>, 'name', 'А')
(<item name="В".../>, 'src', 'b')
(<item name="В".../>, 'name', 'В')
(<item name="C".../>, 'src', 'a')
(<item name="C".../>, 'name', 'С')
(<item name="D".../>, 'src', 'с')
(<item name="D".../>, 'name', 'D')
...
(<item name="H".../>, 'src', 'a')
(<item name="H".../>, 'name', 'H')
В
этом случае функция
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
, но по умолчанию мы будем причислять их к источнику
а
. Соответствующие ключи будут определяться следующим образом:
, значением ключа будет значение этого атрибута, для тех же элементов, у которых атрибута
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>
соответствующее
множество ключей будет определяться следующим образом:
(<item name="А".../>, 'src', 'а')
(<item name="В".../>, 'src', 'b')
(<item name="С".../>, 'src', 'а')
(<item name="D".../>, 'src', 'c')
...
(<item name="H".../>, 'src', 'a')
(<item name="I".../>, 'src', 'a')
(<item name="J".../>, 'src', 'a')
(<item name="K".../>, 'src', 'a')
Функция
key('src', 'a')
возвратит объекты с именами
A
,
C
,
H
,
I
,
J
и
K
.
То, что одни и те же узлы могут иметь разные значения одного ключа, является также очень удобным свойством. Например, два определения ключей, приведенные выше, можно дополнить третьим:
обращаться к объектам, принадлежащим источнику по умолчанию.
Использование множеств узлов в функции key
Функция
key
принимает на вход два аргумента: первым аргументом является строка, задающая имя ключа, в то время как вторым аргументом может быть объект любого типа. В том случае, если аргумент
key-value
в функции
key(key-name, key-value)
является множеством узлов, функция
key
возвратит все узлы, имеющие ключ
key-name
со значением, равным хотя бы одному из строковых значений узла множества
key-value
.
Пример
Предположим, что источники объектов будут сгруппированы следующим образом:
<sources>
<source name="a"/>
<source name="c"/>
</source>
Для того чтобы вычислить множество элементов
item
, принадлежащих любому из источников данной группы, достаточно будет воспользоваться выражением вида
key('src', sources/source/@name)
Множество узлов, выбираемое путем
sources/source/@name
, будет содержать атрибуты
name
элементов
source
. Их строковые значения будут равны
а
и
с
, значит, наше выражение возвратит множество элементов