последовательности в двусмысленных ситуациях, в 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
Форматирование чисел
Мы уже познакомились с функцией языка XPath string
, которая конвертирует свой аргумент в строку. Эта функция может преобразовать в строку и численное значение, но возможности ее при этом сильно ограничены.
К счастью, XSLT предоставляет мощные возможности для форматирования строкового представления чисел при помощи функции format-number
и элемента xsl:decimal- format
.
Функция
Запись функции имеет следующий вид:
Функция format-number
принимает на вход три параметра. Первым параметром является число, которое необходимо преобразовать в строку, применив при этом форматирование. Вторым параметром является образец, в соответствии с которым будет форматироваться число. Третий параметр указывает название десятичного формата, который следует применять.
Образец форматирования в XSLT определяется точно так же, как в классе DecimalFormat
языка Java. Для того чтобы читателю, не знакомому с Java, не пришлось изучать документацию этого языка, мы приведем полный синтаксис образцов форматирования. Продукции образца форматирования мы будем помечать номерами с префиксом NF
, чтобы не путать их с другими продукциями.
Прежде всего, образец форматирования может состоять из двух частей: первая часть определяет форматирование положительного числа, вторая часть — отрицательного. Запишем это в виде EBNF- продукции:
[NF 1] NFPattern ::= NFSubpattern (NFSubpatternDelim NFSubpattern)?
Двум частям образца форматирования соответствуют нетерминалы NFSubpattern
, которые разделены нетерминалом NFSubpatternDelim
.
В случае если вторая часть образца форматирования опушена, отрицательные числа форматируются точно так же, как и положительные, но им предшествует префикс отрицательного числа (по умолчанию — знак 'минус', '-
').