□ Для того чтобы учитывать при подсчете только определенные элементы, можно переписать предыдущее выражение в чуть более строгом виде. Например, выражение, считающее только элементы chapter, будет задаваться следующим образом: (preceding-sibling::chapter) +1.
□ Глубина текущего узла от корня дерева может быть вычислена выражением count(ancestor-or-self::node()). Это выражение будет возвращать 1для корневого узла, 2для элемента документа и так далее.
Вычислять выражения и выводить вычисленные значения в результирующее дерево следует, как и обычно — при помощи элемента xsl:value-of.
Пример
В более сложных ситуациях бывает необходимо подсчитывать узлы, находящиеся на разных уровнях вложенности или удовлетворяющие определенным условиям, начинать отсчет с заданной позиции в документе и использовать при вычислении номера сложные выражения. Использование XPath в таких случаях может быть очень неудобным — выражения будут слишком громоздкими и вычислять их придется в несколько этапов.
Другим, несравненно более легким и удобным способом нумерации и индексирования узлов является использование элемента xsl:number.
Синтаксис элемента описывается следующей конструкцией:
level="single"
| "multiple"
| "any"
count=" паттерн "
from=" паттерн "
value=" выражение "
format="{ строка }"
lang="{ токен }"
letter-value={ "alphabetic"
| "traditional" }
grouping-separator="{ символ }"
grouping-size="{ число }"/>
Элемент xsl:numberвычисляет номер узла в соответствии с заданными критериями, форматирует его и затем вставляет в результирующее дерево в виде текстового узла. То, что все это выполняется в одном элементе преобразования, имеет существенные преимущества по сравнению с использованием XPath-выражений: программа становится более простой и понятной, причем далеко не в ущерб функциональности.
К сожалению, в этом случае, как и во многих других, универсальность использования повлекла за собой семантическую сложность. Несмотря на то, что xsl:numberимеет всего девять атрибутов (причем ни один из них не является обязательным), мы посвятим их описанию значительное количество страниц. Пока же, чтобы сориентировать читателя, мы кратко перечислим назначения атрибутов xsl:number.
□ Атрибут levelуказывает, на каких уровнях дерева следует искать нумеруемые узлы.
□ Атрибут countуказывает, какие именно узлы следует считать при вычислении номера.
□ Атрибут fromуказывает, в какой части документа будет производиться нумерация.
□ Атрибут valueзадает выражения, которые следует использовать для вычисления значения номера.
□ Атрибут formatопределяет, как номер будет форматироваться в строку.
□ Атрибут langзадает языковой контекст нумерации.
□ Атрибут letter-valueопределяет параметры буквенных методов нумерации.
□ Атрибут grouping-separatorзадает символ, разделяющий группы цифр в номере.
□ Атрибут grouping-sizeопределяет количество цифр в одной группе.
Выполнение элемента xsl:numberможно условно разделить на два этапа — вычисление номера и его строковое форматирование. На этапе вычисления активными являются элементы level, count, fromи value. Форматирование производится с учетом значений атрибутов format, lang, letter-value, grouping-separatorи grouping-size. Результатом первого этапа является список номеров, который форматируется в текстовый узел на втором этапе.
Пожалуй, самым простым для понимания (но не самым простым в использовании) способом вычисления номера является использование XPath-выражений. Этот способ практически идентичен использованию xsl:value-of, как было показано в начале этой главы. Единственным отличием xsl:numberявляется то, что после вычисления номера он сначала форматируется, а потом уже вставляется в результирующее дерево в виде текстового узла.
Результатом первого этапа форматирования при определенном атрибуте valueявляется список, состоящий из числа, полученного в результате вычисления выражения, указанного в значении этого атрибута.
Пример
В этом и нескольких следующих примерах мы будем вычислять номера в одном и том же документе, который представлен в листинге 8.31.
Читать дальше