При использовании цифровых форматов нумерации (иными словами, токенов вида
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
, l
etter-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
Запись функции имеет следующий вид:
string format-number(number, string, string?)
Функция
format-number
принимает на вход три параметра. Первым параметром является число, которое необходимо преобразовать в строку, применив при этом форматирование. Вторым параметром является образец, в соответствии с которым будет форматироваться число. Третий параметр указывает название десятичного формата, который следует применять.
Образец форматирования в XSLT определяется точно так же, как в классе
DecimalFormat
языка Java. Для того чтобы читателю, не знакомому с Java, не пришлось изучать документацию этого языка, мы приведем полный синтаксис образцов форматирования. Продукции образца форматирования мы будем помечать номерами с префиксом
NF
, чтобы не путать их с другими продукциями.
Прежде всего, образец форматирования может состоять из двух частей: первая часть определяет форматирование положительного числа, вторая часть — отрицательного. Запишем это в виде EBNF-продукции:
Двум частям образца форматирования соответствуют нетерминалы
NFSubpattern
, которые разделены нетерминалом
NFSubpatternDelim
.
В случае если вторая часть образца форматирования опушена, отрицательные числа форматируются точно так же, как и положительные, но им предшествует префикс отрицательного числа (по умолчанию — знак "минус", "
–
").
Примеры
format-number(1234.567,'#.00;negative #.00')
→
'1234.57'
format-number(-1234.567,'#.00/negative #.00')
→
'negative 1234.57'
format-number(-1234.567,'#.00')
→
'-1234.57'
Каждая из частей образца форматирования состоит из префикса (