Cooper Cripps
Cooper Cripps

Reputation: 205

XSLT format-number function not formatting

I need to format a value to a specific format, but it doesn't appear as though its supported.

I want to use:

format-number($value, '####,##,##,##0')

but the value returned when trying this is '###,###,##0'

So if I $value = '123456789' I want to have the value output as 1,24,56,789 but I am getting 123,456,789.

Are there limitations on what formatting you can do?

If you go to W3schools and enter the following xml:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
<catalog>
    <cd>
        <title>Empire Burlesque</title>
        <artist>Bob Dylan</artist>
        <country>USA</country>
        <company>Columbia</company>
        <price>123456789</price>
        <year>1985</year>
    </cd>
    <cd>
        <title>Hide your heart</title>
        <artist>Bonnie Tyler</artist>
        <country>UK</country>
        <company>CBS Records</company>
        <price>123456789</price>
        <year>1988</year>
    </cd>

</catalog>

and then the following xsl:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
<xsl:variable name="TestFormat" select="'###,##,##,##0'"/>
  <html>
  <body>
  <h2>My CD Collection</h2>
    <table border="1">
      <tr bgcolor="#9acd32">
        <th>Title</th>
        <th>Artist</th>
      </tr>
      <xsl:for-each select="catalog/cd">
      <tr>
        <td><xsl:value-of select="title"/></td>
        <td><xsl:value-of select="format-number(price, $TestFormat)"/></td>
      </tr>
      </xsl:for-each>
    </table>
  </body>
  </html>
</xsl:template>
</xsl:stylesheet>

you can see that I am not getting the desired format. Any suggestions?

Thanks in advance for any help.

Upvotes: 4

Views: 10167

Answers (3)

O. R. Mapper
O. R. Mapper

Reputation: 20731

The grouping separator , is only respected in its first occurrence from the right after the decimal separator. This is because W3C specifies that the format pattern string is in the syntax specified by the JDK 1.1 DecimalFormat class. Looking at that class reveals that it has an integer grouping size property, hence variable group sizes throughout the format cannot be modelled by that class.

Therefore, when writing ###,##,##,##0, the grouping size is set to three (number of digits between the rightmost grouping separator , and the end of the format string, and when writing ###,##,##,0, there will be a grouping separator between each digit.

If you really, really want to do this in XSLT without any external formatting tools/functions, you can probably craft something up by using the string-length, concat and substring functions and inserting the group separators manually.

Update: These statements are only valid for XSLT 1.0.

Upvotes: 1

Michael Kay
Michael Kay

Reputation: 163322

It's really time you moved to XSLT 2.0. With the current release of Saxon your code produces this output:

<html>
   <body>
      <h2>My CD Collection</h2>
      <table border="1">
         <tr bgcolor="#9acd32">
            <th>Title</th>
            <th>Artist</th>
         </tr>
         <tr>
            <td>Empire Burlesque</td>
            <td>12,34,56,789</td>
         </tr>
         <tr>
            <td>Hide your heart</td>
            <td>12,34,56,789</td>
         </tr>
      </table>
   </body>
</html>

Upvotes: 1

earth_tom
earth_tom

Reputation: 831

For 8 and 9 character strings, the following would work:

      <td>
        <xsl:value-of select="substring(price,1,1)"/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="substring(price,2,1)"/>
        <xsl:value-of select="substring(price,4,1)"/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="substring(price,5,2)"/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="substring(price,7,3)"/>
        <xsl:if test="string-length(price) &lt; 9">
          <xsl:value-of select="0"/>
        </xsl:if>
      </td>

Depending on your intent, the "if" block might need to be moved or altered to accomplish slightly different formatting.

Upvotes: 1

Related Questions