следующим условиям:
• он является первым (то есть ближайшим к текущему) узлом, принадлежащим оси ancestor-or-self
текущего узла;
• он удовлетворяет паттерну count
;
• он принадлежит области подсчета;
• если такого узла нет, список номеров будет пустым.
□ На втором шаге вычисляется номер узла уровня. Этот номер будет равен 1
плюс количество узлов, принадлежащих оси навигации preceding-sibling
и удовлетворяющих паттерну count
.
Надо сказать, от атрибута from
в методе single
мало пользы. Единственный эффект, который можно от него получить, — это пустой список номеров в случае, если первый узел, принадлежащий оси ancestor-or-self
и удовлетворяющий паттерну count
, не будет иметь предка, соответствующего паттерну атрибута from
.
Разберем функционирование одноуровневой нумерации в следующем шаблоне:
<xsl:template match='para'>
<xsl:number format=' 1.' count='section'/>
<xsl:number format='1.' count='para'/>
<xsl:value-of select='.'/>
<xsl:text>
</xsl:text>
</xsl:template>
Мы продемонстрируем вычисление номера одного из элементов para
на схематическом изображении дерева обрабатываемого документа (рис. 8.1). Узел обрабатываемого элемента мы выделим полужирной линией, узел элемента doc
пометим буквой d
, узлы элементов chapter
— буквой с
, элементов section
и para — буквами s
и p
соответственно.

Рис. 8.1. Дерево обрабатываемого документа
В качестве первого примера приведем вычисление номера элементом
<xsl:number format=' 1.' count='section'/>
На первом шаге нам нужно найти узел уровня дерева. Этим узлом будет первый элемент section
, являющийся предком текущего узла. На рис. 8.2 он обведен пунктиром.

Рис. 8.2. Первый шаг вычисления номера
Номер этого элемента будет равен 1
плюс количество предшествующих ему братских элементов section
. Это множество выделено пунктиром на рис. 8.3.

Рис. 8.3. Второй шаг вычисления номера
Выделенное множество содержит два узла. Таким образом, искомый номер будет равен 3
.
Проведем такой же разбор для определения
<xsl:number format='1.' count='para'/>
В этом случае паттерну, указанному в элементе count
удовлетворяет сам текущий узел, значит, он и будет являться узлом уровня, как это показано на рис. 8.4.

Рис. 8.4. Первый шаг вычисления номера
Выделим множество элементов para
, являющихся братьями узла уровня и предшествующих ему (рис. 8.5).

Рис. 8.5. Второй шаг вычисления номера
Выделенное множество содержит всего один узел, значит, искомый номер будет равен 2
.
Таким образом, результатом обработки выделенного элемента para
будет следующая строка:
3.2.paragraph 14
Метод multiple
похож на метод single
, но при этом он немного сложнее, поскольку вычисляет номера узлов сразу на нескольких уровнях дерева. Нумерацию с применением метода multiple
называют также многоуровневой нумерацией.
Область нумерации метода multiple
определяется так же, как и в случае с методом single
: учитываются только потомки ближайшего предка текущего узла, удовлетворяющего паттерну, указанному в атрибуте from
.
Вычисление списка номеров узлов выполняется в два этапа:
□ На первом этапе выбирается множество нумеруемых узлов, удовлетворяющее следующим условиям:
• его узлы принадлежат оси навигации ancestor-or-self
текущего узла;
• его узлы соответствуют паттерну count
;
• его узлы принадлежат области подсчета.
□ На втором этапе для каждого узла нумеруемого множества вычисляется позиция среди собратьев. Позиция нумеруемого узла будет равна 1
плюс количество узлов, принадлежащих его оси навигации preceding-sibling
и соответствующих паттерну count
.
Для демонстрации вычисления номеров на нескольких уровнях дерева документа проследим за выполнением инструкции
<xsl:number
format=' 1.1.'
level='multiple'
count='doc|chapter|para'
from='doc'/>
при обработке того же элемента para
.
Прежде всего, надо определить область подсчета. Значением атрибута from
является паттерн doc
, значит, подсчет будет вестись среди всех потомков ближайшего к текущему элементу para
предка, который является элементом doc
. Это множество выделено на рис. 8.6 штрих-пунктирной линией.

Рис. 8.6. Определение области подсчета
Следующим шагом выберем узлы, принадлежащие оси навигации ancestor-or-self
текущего узла para и удовлетворяющие паттерну doc|chapter|para
. Это множество будет включать сам текущий элемент, а также его предки chapter
и doc
. На рис. 8.7 они обведены пунктиром.

Рис. 8.7. Первый шаг вычисления номера
Следующим шагом оставим только те из выбранных узлов, которые входят в область подсчета. Эти узлы обведены на рис. 8.8 пунктиром.

Рис. 8.8. Второй шаг вычисления номера
Мы получили множество узлов, состоящее всего из двух элементов — chapter
и para
вследствие того, что элемент doc
был исключен как не входящий в