Re: [xsl] Format-Number Function

Subject: Re: [xsl] Format-Number Function
From: "Jay Bryant" <jay@xxxxxxxxxxxx>
Date: Mon, 14 Mar 2005 22:27:15 -0600
> I'm using Livelink and I wouldn't be surprised if it's a bug but if there
is it's going to really screw me up.  Here's the xsl line:
>
> <td class="number"><xsl:value-of select="format-number(./Total_Cost,
'#,###,###')"/></td>
>
> The xml is basically like this:
> <Florida2004A>
> <Total_Cost>3603664</Total_Cost>
> </Florida2004A>
>
> It comes back to me as '3.' There is no xsl:decimal-format specification
in my code.  Again, this does format correctly for any number with 6 digits
or less.  Any suggested work around or other ideas? (other than a new
processor?)  I guess I could use string functions to format correctly.
>

I tested format-number in Saxon 8, and it works as expected (produces
3,603,664), so it looks like Livelink has a bug. String functions will give
you a work around. If the string is arbitrarily long, it'll need to be
recursive, like this one:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

  <xsl:template match="/">
    <xsl:call-template name="makeNumber">
      <xsl:with-param name="inString" select="cost/Total_Cost"/>
    </xsl:call-template>
  </xsl:template>

  <xsl:template name="makeNumber">
    <xsl:param name="inString"/>
    <xsl:choose>
      <xsl:when test="string-length($inString) &lt; 4">
        <xsl:value-of select="$inString"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:variable name="modNum" select="string-length($inString) mod
3"/>
        <xsl:choose>
          <xsl:when test="$modNum = 0">
            <xsl:variable name="result"><xsl:value-of
select="substring($inString, 1, 3)"/>,</xsl:variable>
            <xsl:value-of select="$result"/>
            <xsl:call-template name="makeNumber">
              <xsl:with-param name="inString" select="substring($inString,
4, string-length($inString))"/>
            </xsl:call-template>
          </xsl:when>
          <xsl:otherwise>
            <xsl:variable name="result"><xsl:value-of select="substring($inS
tring, 1, $modNum)"/>,</xsl:variable>
            <xsl:value-of select="$result"/>
            <xsl:call-template name="makeNumber">
              <xsl:with-param name="inString" select="substring($inString,
$modNum + 1, string-length($inString))"/>
            </xsl:call-template>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>

I tested that against this midget XML file:

<cost>
  <Total_Cost>3603664</Total_Cost>
</cost>

Also, I tested it from 0 to 10 digits. It worked in all cases.

I suppose there's a mathematical solution to this problem, too, but it felt
more like a string problem since it requires commas.

By the way, you don't need the ./ before Total_Cost in your template.

Jay Bryant
Bryant Communication Services
(writing from home for once)

Current Thread