XSLT - Formatting Numbers with <xsl:decimal-format> in XSLT

The <xsl:decimal-format> element in XSLT is used to define how numbers should be formatted when they are converted into text using functions such as format-number(). It allows developers to specify symbols and rules for displaying numbers, decimals, percentages, currencies, and other numeric values in a customized way.

By default, XSLT provides a standard decimal format. However, applications sometimes require numbers to be displayed according to a particular convention. For example, a value such as 1234567.89 might need to appear as 1,234,567.89, 1.234.567,89, or $1,234,567.89. The <xsl:decimal-format> declaration makes it possible to define these formatting rules.

Basic Syntax

The general syntax is:

<xsl:decimal-format
    name="formatName"
    decimal-separator="."
    grouping-separator=","
    infinity="Infinity"
    minus-sign="-"
    NaN="NaN"
    percent="%"
    per-mille="‰"
    zero-digit="0"
    digit="#"
    pattern-separator=";"
    exponent-separator="E"/>

The attributes specify the symbols that should be used while formatting numbers.

For example:

<xsl:decimal-format
    name="standardFormat"
    decimal-separator="."
    grouping-separator=","/>

Here, a decimal point is used to separate the fractional part, while a comma is used to separate groups of thousands.

Why <xsl:decimal-format> Is Used

Number formatting becomes important when XML data is intended for presentation to users. XML normally stores values in a machine-readable form, such as:

<price>1250000.75</price>

The value is useful for processing, but displaying it directly may not provide the desired presentation. XSLT can transform it into:

1,250,000.75

A decimal format can define the symbols used for this transformation.

This is particularly useful for applications that need to support different regional conventions. Some countries use a comma as the decimal separator and a period as the grouping separator. For example:

1.250.000,75

The corresponding XSLT declaration could be:

<xsl:decimal-format
    name="europeanFormat"
    decimal-separator=","
    grouping-separator="."/>

Using a Named Decimal Format

A decimal format can be given a name and then referenced by the format-number() function.

Example:

<xsl:decimal-format
    name="customFormat"
    decimal-separator="."
    grouping-separator=","/>

<xsl:value-of select="format-number(1234567.89, '#,##0.00', 'customFormat')"/>

The output will be:

1,234,567.89

The third argument of format-number() identifies the decimal format that should be used.

Important Attributes

The decimal-separator attribute specifies the character used between the integer and fractional parts of a number.

<xsl:decimal-format decimal-separator="."/>

For example:

125.50

The grouping-separator attribute specifies the character used to separate groups of digits.

<xsl:decimal-format grouping-separator=","/>

This can produce:

1,000,000

The minus-sign attribute defines the symbol used for negative numbers. Normally, this is a hyphen:

<xsl:decimal-format minus-sign="-"/>

The percent attribute defines the symbol used when formatting percentages:

<xsl:decimal-format percent="%"/>

The per-mille attribute defines the symbol representing one part per thousand:

<xsl:decimal-format per-mille="‰"/>

The infinity attribute specifies how positive or negative infinity should be represented.

<xsl:decimal-format infinity="Infinity"/>

The NaN attribute specifies the text displayed when a value is "Not a Number."

<xsl:decimal-format NaN="Not a Number"/>

Example with XML Data

Consider the following XML:

<products>
    <product>
        <name>Laptop</name>
        <price>125499.75</price>
    </product>
    <product>
        <name>Monitor</name>
        <price>45999.50</price>
    </product>
</products>

An XSLT stylesheet can define a decimal format:

<xsl:decimal-format
    name="currencyFormat"
    decimal-separator="."
    grouping-separator=","/>

<xsl:template match="/">
    <html>
        <body>
            <xsl:for-each select="products/product">
                <p>
                    <xsl:value-of select="name"/>
                    <xsl:text>: </xsl:text>
                    <xsl:value-of
                        select="format-number(price, '#,##0.00', 'currencyFormat')"/>
                </p>
            </xsl:for-each>
        </body>
    </html>
</xsl:template>

The resulting output can be:

Laptop: 125,499.75
Monitor: 45,999.50

The important point is that <xsl:decimal-format> defines the symbols and conventions, while format-number() applies those rules to a particular numeric value.

Decimal Formatting and format-number()

<xsl:decimal-format> and format-number() are closely related but serve different purposes.

<xsl:decimal-format> defines the formatting environment:

<xsl:decimal-format
    name="custom"
    decimal-separator=","
    grouping-separator="."/>

format-number() performs the actual formatting:

format-number(1234567.89, '#.##0,00', 'custom')

Therefore, the decimal format can be viewed as a reusable configuration for numeric presentation.

Multiple Decimal Formats

A stylesheet can define multiple named decimal formats when an application needs different numeric conventions.

For example:

<xsl:decimal-format
    name="usFormat"
    decimal-separator="."
    grouping-separator=","/>

<xsl:decimal-format
    name="europeFormat"
    decimal-separator=","
    grouping-separator="."/>

Different formats can then be selected depending on the required output.

This is useful in multilingual or international applications where the same XML data may need to be presented according to different regional conventions.

Advantages

Using <xsl:decimal-format> provides several benefits. It separates numeric presentation rules from the underlying XML data, making transformations easier to maintain. It also allows the same formatting rules to be reused throughout a stylesheet. Named decimal formats are particularly useful when an application produces output for different regions or uses different numeric conventions.

Another advantage is consistency. Instead of manually inserting commas, decimal symbols, or percentage symbols into output, the XSLT processor can apply the defined rules automatically.

Conclusion

<xsl:decimal-format> is an XSLT declaration used to customize the symbols and conventions employed when numbers are formatted. It works primarily with format-number() and can control elements such as decimal separators, grouping separators, percentage symbols, negative signs, infinity, and NaN.

It is especially valuable when an XSLT transformation needs to present numerical XML data in a consistent, user-friendly, or region-specific format. By defining named decimal formats, developers can reuse formatting rules and keep numeric presentation separate from the actual data.