Выбрать главу

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

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

Пример

Элемент xsclass="underline" number вида

<xsclass="underline" 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 ее родительского узла:

<xsclass="underline" template match="section">

 <xsclass="underline" number

  format="{../@format}-1 "

  level="multiple"

  count="chapter|section"/>

 <xsclass="underline" value-of select="@title"/>

</xsclass="underline" 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 и элемента xsclass="underline" decimal-format.

Функция format-number

Запись функции имеет следующий вид:

string format-number(number, string, string?)

Функция format-number принимает на вход три параметра. Первым параметром является число, которое необходимо преобразовать в строку, применив при этом форматирование. Вторым параметром является образец, в соответствии с которым будет форматироваться число. Третий параметр указывает название десятичного формата, который следует применять.

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

Прежде всего, образец форматирования может состоять из двух частей: первая часть определяет форматирование положительного числа, вторая часть — отрицательного. Запишем это в виде EBNF-продукции:

[NF 1] NFPattern ::= NFSubpattern (NFSubpatternDelim NFSubpattern)?

Двум частям образца форматирования соответствуют нетерминалы 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'

Каждая из частей образца форматирования состоит из префикса (NFPrefix), целой части (NFInteger), необязательной дробной части (NFFractional) и суффикса (NFSuffix).

[NF 2] NFSubpattern ::= NFPrefix NFinteger NFFractional? NFSuffix

Префикс или суффикс образца форматирования могут содержать символ процента. Если суффикс содержит символ процента, число должно быть умножено на 100 и выведено со знаком процента. Наличие символа процента в префиксе на форматирование не влияет.

Пример

format-number(0.45,'0.00%') '45.00%'

format-number(0.45,'0.##%') '45.00%'

format-number(0.45678,'%0.00') '%0.46'

format-number(0.45678,'0.####%') '45.678%'

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

[NF 3] NFPrefix ::= (NFChar NFPercent?)*

[NF 4] NFSuffix ::= (NFChar NFPercent?)*

Пример

Если мы хотим заключить наше число, к примеру, в квадратные скобки, мы должны будем включить в его образец форматирования префикс "[" и суффикс "]":

format-number(123456, '[#]') '[123456]'