Валиков Алексей Н.
Шрифт:
<item source="a" name="F"/>
</items>
Для элементов
item
мы будем генерировать ключи, значения которых будут состоять из двух частей — источника и имени, разделенных символом "–
". Для того чтобы решить одним ключом все три поставленные задачи, мы будем использовать для его определения три элемента xsl:key
. Листинг 8.28. Входящий документ
<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>
Листинг 8.29. Выходящий документ
<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 в паттернах
Разбирая синтаксические правила построения паттернов, мы встретились с особой формой паттерна, в котором могла использоваться функция
key
. Приведем еще раз эту продукцию: [PT3] IdKeyPattern ::= 'id' '(' Literal ')'
| 'key' '(' Literal ',' Literal ')'
Функция
key(key-name, key-value)
в паттерне будет соответствовать узлам, значение ключа key-name
которых равняется или принадлежит объекту key-value
. Это позволяет использовать возможности ключей при проверке узлов на соответствие образцу. Пример
Предположим, что нам нужно по-особому обработать объекты, принадлежащие источнику
а
. Для этого мы можем создать шаблон следующего вида. Листинг 8.30. Шаблон, использующий функцию key в паттерне
<xsl:template match="key('src', 'a')">
<!-- Содержимое шаблона -->
</xsl:template>
Этот шаблон будет применяться к любым узлам, имеющим ключ
src
со значением а
.