Чтение онлайн

ЖАНРЫ

Технология XSLT

Валиков Алексей Н.

Шрифт:

Кроме того, XSLT предоставляет похожий механизм, механизм ключей, который выбирает узлы не по уникальным атрибутам, а по значениям именованных ключей, определенных в преобразовании. Для этого служит функция

key
.

Поскольку два этих механизма схожи по семантике, они определяются в XSLT в едином паттерне:

[PT3] IdKeyPattern ::= 'id' '(' Literal ')'

| 'key' '(' Literal ',' Literal ')'

Этому паттерну соответствуют только узлы, принадлежащие результату одной из двух функций —

id
или
key
.

Оставим

детали использования ключей и
ID
– атрибутов на потом и вернемся к разбору вариантов синтаксиса паттернов.

□ Паттерну

IdKeyPattern '/' RelativePathPattern
соответствуют узлы, которые соответствуют образцу пути
RelativePathPattern
отсчитанного относительного узла, соответствующего
IdKeyPattern
. Например, узел соответствует паттерну
id('index5')/a/b
, если он является элементом с именем
b
, его родителем является элемент
а
, а его родитель в свою очередь имеет уникальный атрибут со значением
"index5"
.

□ Паттерн

IdKeyPattern '//' RelativePathPattern
аналогичен предыдущему: ему соответствуют узлы, которые соответствуют паттерну
RelativePathPattern
, отсчитанному от любого потомка или самого узла, входящего в
IdKeyPattern
. Например, паттерну
id('index5')//a/b
будет соответствовать любой дочерний элемент
b
элемента
a
, являющегося потомком элемента, уникальный атрибут которого имеет значение
index5
, или если он сам имеет такой атрибут.

Мы более подробно остановимся на ключевых паттернах, когда будем разбирать функции

id
и
key
, а пока обратимся к главной детали всех вышеперечисленных продукций — к образцу относительного пути,
RelativePathPattern
. Его продукция записывается в следующем виде:

[PT4] RelativePathPattern

 ::= StepPattern

| RelativePathPattern '/' StepPattern

| RelativePathPattern '//' StepPattern

Если сравнить это правило с упрощенной продукцией

RelativeLocationPath
, можно заметить совпадение с точностью до имен продукций. Образец относительного пути строится точно так же, как и обычный путь выборки — перечислением через разделяющие символы
"/"
и
"//"
шагов, в данном случае — шагов образца относительного пути.

Эти шаги соответствуют продукции

StepPattern
, которая отличается от продукции
Step
только тем, что разрешает использовать только оси
child
и
attribute
.

[PT5] StepPattern ::= ChildOrAttributeAxisSpecifier NodeTest

Predicate*

Продукция

ChildOrAxisSpecifier
описывает дескрипторы осей
child
и
attribute
в полном или сокращенном виде:

[P6] ChildOrAttributeAxisSpecifier

 ::= AbbreviatedAxisSpecifier

| ('child' | 'attribute') '::'

Для

простоты мы можем раскрыть эту продукцию, получив ее в следующем виде:

ChildOrAttributeAxisSpecifier

 ::= '@' ?

| 'child::'

| 'attribute::'

Тогда продукцию

StepPattern
тоже можно переписать:

StepPattern ::= NodeTest Predicate*

| '@' NodeTest Predicate*

| 'child::' NodeTest Predicate*

| 'attribute::' NodeTest Predicate*

Теперь стало совершенно очевидно, что шаг паттерна это не что иное, как подмножество шагов выборки, в которых ограничено множество осей навигации.

Таким образом, синтаксически паттерны отличаются от путей выборки тем, что в них можно использовать только две оси навигации (не считая

descendant-or-self
в виде оператора), но зато можно в качестве узла отсчета использовать узел, выбранный по своему уникальному атрибуту или по значению ключа.

Паттерны могут использоваться в XSLT в следующих атрибутах:

□ атрибуты

count
и
from
элемента
xsl:number
;

□ атрибут

match
элемента
xsl:key
;

□ атрибут

match
элемента
xsl:template
.

Последние два случая паттернов отличаются от первого тем, что в них нельзя использовать переменные. Определение вида

<xsl:template match="*[name = $name]">

 ...

</xsl:template>

будет некорректным.

Семантика паттернов

Остановимся подробнее на вопросе — что же означает "соответствие узла некоторому паттерну".

Прежде всего, заметим, что любой паттерн является также и XPath-выражением. Тогда строгое определение соответствия узла паттерну можно дать следующим образом.

Узел

X
соответствует паттерну
P
тогда и только тогда, когда существует такой узел
Y
, принадлежащий оси
ancestor-or-self
узла
X
, что множество, получаемое в результате вычисления выражения
P
в контексте узла
Y
будет содержать узел
X
.

Пример

Рассмотрим это определение на примере паттерна

body//а
. Строго говоря, узел будет соответствовать этому паттерну, если во множестве его предков (плюс сам узел) найдется такой узел, что множество
body//а
, вычисленное в его контексте, будет содержать проверяемый узел. На практике первые два элемента
а
приведенного ниже документа соответствуют этому паттерну, потому что существует элемент
html
, содержащий элемент
body
, потомками которого эти элементы
а
являются.

Поделиться с друзьями: