Ключи являются важным аспектом XSLT. Вместо того, чтобы перестраивать их, лучше изучить концепцию.
Ключи можно понимать как таблицы с узлами, хранящимися под указанными c ключами. Они определены так:
<xsl:key name="addressByStreet" match="address" use="street"/>
Атрибут name
- это просто QName (аналогично имени переменной). Атрибут match
содержит выражение XPath, которое работает аналогично атрибуту match
<xsl:template>
. Когда процессор находит узел, который соответствует выражению, он оценивает выражение XPath атрибута use
в контексте сопоставленного элемента. Если это выражение возвращает значения, они будут использоваться для создания новых записей в «таблице ключей» для соответствующего элемента.
Для иллюстрации этого: Приведенный выше ключ создает таблицу со всеми элементами <address>
в обработанный документ, набранный по значению их <street>
потомка. Это означает, что если у вас есть эти элементы:
<address>
<street>Main Street</street>
<number>123</number>
</address>
<address>
<street>Main Street</street>
<number>456</number>
</address>
<address>
<street>Country Road</street>
<street>Country Rd.</street>
<number>789</number>
</address>
… вы можете использовать key('addressByStreet', 'Main Street')
для получения всех перечисленных адресов на главной улице.
Вы можете использовать как key('addressByStreet', 'Country Road')
, так и key('addressByStreet', 'Country Rd.')
для получения последнего адреса.
Зачем здесь использовать ключи? Вышеупомянутое выражение может быть реализовано как //address[street='Main Street']
, но теперь каждый раз, когда вызывается это выражение, процессор XSLT, вероятно, снова просматривает весь документ. Это проблема, если шаблон или l oop вызывается часто. Ключи могут иметь огромное преимущество в производительности (например, снизить сложность с O (n²) до O (n)), поскольку результаты «кэшируются».
Существует множество приложений и шаблонов, в которых используются ключи. Например, если у вас есть это XML:
<street-list>
<street>Main Street</street>
<street>Bumpy Road</street>
</street-list>
Выражение street-list/street[not(key('addressByStreet', .))]
отфильтрует список улиц и вернет только улицы, для которых нет адреса в вышеприведенном списке, т.е. только "Bumpy Road" "в этом случае, потому что для" Main Street "существует ключевая запись.
Типичным применением ключей в XSLT 1 является мюнхенская группировка .