Книга: Технология XSLT

Форматирование номеров

Форматирование номеров

Возвращаясь немного назад, напомним, что результатом первого этапа выполнения xsl:number является список номеров, который может быть пустым или содержать одно или несколько чисел. Несложно увидеть, что количество номеров в этом списке будет зависеть от следующих условий.

? Список номеров будет пустым, если в области нумерации не оказалось нумеруемых узлов.

? Список номеров будет состоять не более чем из одного числа при использовании методов single и any.

? Список номеров будет состоять из нуля или более чисел (по одному на каждый уровень нумерации) при использовании метода multiple.

На этапе форматирования список номеров преобразуется в строку и вставляется результирующее дерево в виде текстового узла.

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

Форматирование списка номеров производится в соответствии со значениями атрибутов format, lang, letter-value, grouping-separator и grouping-size, назначение и использование которых мы и будем разбирать в этом разделе.

Основным атрибутом форматирования является атрибут format, который содержит последовательность форматирующих токенов. Каждый форматирующий токен состоит из букв и цифр; он определяет процедуру форматирования для каждого числа из списка форматируемых номеров. В значении атрибута format форматирующие токены отделяются друг от друга сочетаниями символов, которые не являются буквами и цифрами. Такие сочетания называются разделяющими последовательностями. При форматировании они остаются в строковом выражении номера без изменений.

Пример

В примере к методу multiple мы использовали следующий элемент xsl:number:

<xsl:number
 format="     1.1."
 level="multiple"
 count="doc|chapter|para"
 from="doc"/>

Разберем строение атрибута format этого элемента (на рис. 8.12 пробелы обозначены символами "?"):


Рис. 8.12. Строение атрибута format элемента xsl:number

Список номеров в том примере состоял из номера элемента chapter (числа 2) и номера элемента para (тоже 2). Номер, генерируемый элементом xsl:number, будет состоять из:

? разделяющей последовательности "?????", которая будет скопирована, как есть;

? числа 2, которое получается в результате форматирования номера 2 форматирующим токеном "1";

? разделяющего символа ".";

? числа 2, которое получается в результате форматирования номера 2 вторым форматирующим токеном "1";

? разделяющего символа ".".

Объединив все эти части, мы получим отформатированный номер "?????2.2".

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

Таблица 8.3. Форматирующие токены

Токен Описание Примеры
Токен Преобразование
1 Форматирует номер в виде строкового представления десятичного числа 1 1 ? '1'
1 2 ? '2'
1 10 ? '10'
1 999 ? '999'
1 1000 ? '1000'
0...01 Форматирует номер в виде строкового представления десятичного числа; если получившая строка короче токена, она дополняется предшествующими нулями 0001 1 ? '0001'
001 2 ? '002'
001 10 ? '010'
01 999 ? '999'
00001 1000 ? '01000'
A Форматирует номер в виде последовательности заглавных букв латинского алфавита A 1 ? 'A'
A 2 ? 'B'
A 10 ? 'J'
A 27 ? 'AA'
A 999 ? 'ALK'
A 1000 ? 'ALL'
a Форматирует номер в виде последовательности строчных букв латинского алфавита a 1 ? 'a'
a 2 ? 'b'
a 10 ? 'j'
a 27 ? 'aa'
a 999 ? 'alk'
a 1000 ? 'all'
I Форматирует номер заглавными римскими цифрами I 1 ? 'I'
I 2 ? 'II'
I 10 ? 'X'
I 27 ? 'XXVII'
I 999 ? 'IM'
I 1000 ? 'M'
i Форматирует номер строчными римскими цифрами i 1 ? 'i'
i 2 ? 'ii'
i 10 ? 'x'
i 27 ? 'xxvii'
i 999 ? 'im'
i 1000 ? 'm'
Другой Форматирует номер k как k-й член последовательности, начинающейся этим токеном. Если нумерация таким токеном не поддерживается, вместо него используется токен 1. Не поддерживающийся токен 1 ? '1'
b 10 ? 'k'
Б 2 ? 'В'
Б 27 ? 'Ы'
? 999 ? '???'
? 1000 ? '???'

При использовании алфавитной нумерации процессор может учитывать значение атрибута lang элемента xsl:number для того, чтобы использовать буквы алфавита соответствующего языка. Однако на практике возможность эта поддерживается очень слабо: большинство процессоров поддерживают алфавитную нумерацию только с использованием латиницы. Поэтому для того, чтобы использовать при алфавитной нумерации кириллицу, вместо атрибута lang следует использовать форматирующие токены "&#x410;" (русская заглавная буква "А") и "&#х430;" (русская строчная буква "а").

Пример

Для форматирования номеров в последовательности 1.1.a, 1.1.б, 1.1.в, …, 1.2.а и так далее можно использовать объявление вида:

<xsl:number
 format="1.&#х430;"
 level="multiple"
 count="chapter|section"
 from="doc"/>

Представим теперь себе следующую ситуацию: нам нужно начать нумерацию с латинской буквы i для того, чтобы получить последовательность номеров вида i, j, k, l, m и так далее. Первое, что приходит в голову — это запись вида

<xsl:number format="i" ... />

Однако вместо требуемой последовательности мы получим последовательность строчных римских цифр: i, ii, iii и так далее. Иными словами, некоторые форматирующие токены определяют нумерующую последовательность двусмысленно: одним вариантом является алфавитная последовательность, начинающаяся этим токеном, другим — некая традиционная для данного языка (например, последовательность римских цифр для английского).Для того чтобы различать эти последовательности в двусмысленных ситуациях, в xsl:number существует атрибут letter-value. Если его значением является "alphabetic", нумерующая последовательность является алфавитной, значение "traditional" указывает на то, что следует использовать традиционный для данного языка способ. Если атрибут letter-value опущен, процессор может сам выбирать между алфавитным и традиционным способами нумерации.

При использовании цифровых форматов нумерации (иными словами, токенов вида 1, 01, 001 и так далее) цифры в номере можно разделить на группы, получив, например, такие номера как "2.00.00" из 20000 или "0-0-0-2" из 2. Для этой цели в xsl:number используется пара атрибутов grouping-separator и grouping-size.

Атрибут grouping-separator задает символ, который следует использовать для разбивки номера на группы цифр, в то время как grouping-size указывает размер группы. Эти атрибуты всегда должны быть вместе — если хотя бы один из них опущен, второй просто игнорируется.

Пример

Элемент xsl:number вида

<xsl:number
 format="[00000001]"
 grouping-separator="."
 grouping-size="2"/>

будет генерировать номера в следующей последовательности:

1 ? '[00.00.00.01]'
2
? '[00.00.00.02]'
...
999
? '[00.00.09.99]'
1000
? '[00.00.10.00]'

Пожалуй, следует упомянуть, что в значениях атрибутов format, lang, letter-value, grouping-size и grouping-separator могут быть указаны шаблоны значений, иными словами могут использоваться выражения в фигурных скобках. Это может быть полезно, например, для того, чтобы сгенерировать форматирующие токены во время выполнения преобразования.

Пример

В следующем шаблоне формат номера секции зависит от значения атрибута format ее родительского узла:

<xsl:template match="section">
 <xsl:number
  format="{../@format}-1 "
  level="multiple"
  count="chapter|section"/>
 <xsl:value-of select="@title"/>
</xsl:template>

При обработке входящего документа

<doc>
 <chapter format="I" title="First Chapter">
  <section title="First Section"/>
  <section title="Second Section"/>
  <section title="Third Section"/>
 </chapter>
</doc>

нумерация секций будет выглядеть как

I-1 First Section
I-2 Second Section
I-3 Third Section

Если же атрибут format элемента chapter будет иметь значение 1, секции будут пронумерованы в виде

1-1 First Section
1-2 Second Section
1-3 Third Section

Оглавление книги


Генерация: 1.118. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз