<item source='b' name='F'/>
<item source='a' name='C'/>
<item source='c' name='G'/>
<item source='a' name='H'/>
<item source='a' name='B'/>
<item source='b' name='G'/>
<item source='c' name='H'/>
<item source='c' name='C'/>
<item source='c' name='D'/>
<item source='b' name='A'/>
<item source='a' name='B'/>
<item source='c' name='D'/>
<item source='c' name='E'/>
<item source='a' name='F'/>
</items>
Для элементов item
мы будем генерировать ключи, значения которых будут состоять из двух частей — источника и имени, разделенных символом '-
'. Для того чтобы решить одним ключом все три поставленные задачи, мы будем использовать для его определения три элемента xsl:key
.
<xsl:stylesheet
version='1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:key name='src' match='item' use='concat(@source,'-')'/>
<xsl:key name='src' match='item' use='concat('-', @name)'/>
<xsl:key name='src' match='item' use='concat(@source, '-', @name)'/>
<xsl:template match='/'>
<result>
<items source='a' name='B'>
<xsl:copy-of select='key('src', 'a-B')'/>
</items>
<items name='B'>
<xsl:copy-of select='key('src', '-B')'/>
</items>
<items source='a'>
<xsl:copy-of select='key('src', 'a-')'/>
</items>
</result>
</xsl:template>
</xsl:stylesheet>
<result>
<items source='a' name='B'>
<item source='a' name='B'/>
<item source='a' name='B'/>
</items>
<items name='B'>
<item source='b' name='B'/>
<item source='a' name='B'/>
<item source='a' name='B'/>
</items>
<items source='a'>
<item source='a' name='A'/>
<item source='a' name='C'/>
<item source='a' name='H'/>
<item source='a' name='B'/>
<item source='a' name='B'/>
<item source='a' name='F'/>
</items>
</result>
У приведенного здесь способа формирования ключа есть определенные ограничения: необходимо иметь априорную информацию о строковых значениях каждого из свойств, составляющих наш композитный ключ для того, чтобы корректно формировать его строковые представления. Например, если бы в приведенном выше документе имена объектов и источников могли бы содержать символ '-
', было бы непонятно, к какому объекту относится составной ключ 'a-b-c
': к объекту с источником a-b
и именем с
или к объекту с источником а
и именем b-c
. К счастью, в большинстве случаев такая информация имеется, и генерировать составные ключи не очень сложно.
Функция
Разбирая синтаксические правила построения паттернов, мы встретились с особой формой паттерна, в котором могла использоваться функция key
. Приведем еще раз эту продукцию:
[PT3] IdKeyPattern ::= 'id' '(' Literal ')'
| 'key' '(' Literal ',' Literal ')'
Функция key(
в паттерне будет соответствовать узлам, значение ключа key-name
которых равняется или принадлежит объекту key-value
. Это позволяет использовать возможности ключей при проверке узлов на соответствие образцу.
Предположим, что нам нужно по-особому обработать объекты, принадлежащие источнику а
. Для этого мы можем создать шаблон следующего вида.
<xsl:template match='key('src', 'a')'>
<!-- Содержимое шаблона -->
</xsl:template>
Этот шаблон будет применяться к любым узлам, имеющим ключ src
со значением а
.
Нумерация