• @ префикс :*
или attribute:: префикс :*
— выбор всех атрибутов в определенном пространстве имен.
Примеры паттернов с приоритетом, равным -0.25
:
• fo:*
— выбор всех дочерних элементов в пространстве имен с префиксом fo
;
• attribute::xsl:*
— выбор всех атрибутов текущего элемента, которые находятся в пространстве имен с префиксом xsl
.
□ Если паттерн состоит из проверки узла ( NodeTest
), которой предшествует ChildOrAttributeAxisSpecifier
, приоритет шаблона будет равен -0.5
. Паттерны такого рода будут выглядеть как:
• NodeTest
или child:: NodeTest
— выбор всех дочерних узлов, соответствующих данной проверке;
• QNodeTest
или attribute:: NodeTest
— выбор всех атрибутов, соответствующих данной проверке.
□ Примеры паттернов с приоритетом, равным -0.5
:
• text()
— выбор дочерних текстовых узлов;
• child::comment()
— выбор дочерних комментариев;
• @*
— выбор всех атрибутов данного шаблона.
□ Если ни одно из предыдущих условий не выполняется, приоритет шаблона равен 0.5
.
Для удобства использования составим таблицу (табл. 5.1) с приоритетами тех или иных паттернов.
Таблица 5.1. Приоритет паттернов
Вид паттерна |
Приоритет |
QName |
0 |
child:: QName |
@ QName |
attribute:: QName |
processing-instruction( литерал ) |
child::processing-instruction( литерал ) |
префикс :* |
-0.25 |
child:: префикс :* |
@ префикс :* |
attribute:: префикс :* |
NodeTest |
-0.5 |
child:: NodeTest |
@ NodeTest |
attribute:: NodeTest |
Другие паттерны |
0.5 |
Несмотря на то, что вычислением приоритета преобразований занимается процессор, полезно понимать механизм этого вычисления для того, чтобы уметь предсказывать, как будет решен конфликт тех или иных шаблонов. Довольно часто в преобразованиях допускаются ошибки, связанные с приоритетом применения шаблонов.
Пример
Вычислим в качестве упражнения приоритеты шаблонов для следующего примера.
Листинг 5.15. Преобразование
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:a="a">
1
2
3
4
5
template matched
.
Пять шаблонов этого преобразования могут соответствовать одним и тем же узлам, а значит, создавать множество конфликтов, которые будут разрешаться при помощи механизма приоритетов.
Приоритет первого шаблона, паттерн которого соответствует продукции QName, будет равен 0
. Приоритет второго шаблона будет равен 0.5
, поскольку его паттерн не удовлетворяет другим условиям. Паттерн третьего шаблона имеет вид NCName:*
, а значит, его приоритет равен -0.25
. Приоритет четвертого шаблона равен -0.5
, поскольку его паттерн является проверкой узла ( NodeTest
). Приоритет последнего, пятого шаблона будет равен 0, поскольку паттерн b
соответствует продукции QName
.
Попробуем применить это преобразование к следующему документу:
Проследим за тем, как будет выполняться преобразование.
□ Инструкции по обработке ,
которая идет в документе первой, соответствует только один, четвертый шаблон.
□ Корневому элементу b
соответствуют два шаблона — четвертый и пятый, однако приоритет пятого шаблона выше, и поэтому применен будет именно он.
□ Следующему элементу, a
, соответствуют третий и четвертый шаблоны. Здесь процессор должен применить третий шаблон, так как его приоритет выше, чем приоритет четвертого шаблона.
□ Элемент b
, включенный в элемент а
, соответствует первому, второму, третьему и четвертому шаблонам. Наивысший приоритет из них имеет второй шаблон.
□ Следующему элементу b
соответствуют первый, третий и четвертый шаблоны. В этом случае процессор выберет первый шаблон.
□ Элемент с
соответствует третьему и четвертому шаблонному правилу. В этом случае процессор должен будет использовать третий шаблон.
Сравнивая этот анализ с сообщениями процессора, можно убедиться в верности прогноза:
4 template matched ORA.
5 template matched b.
3 template matched a.
2 template matched b.
1 template matched b.
Читать дальше