Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what is correct way to test for xs:decimal in XSL?

Tags:

xslt

I'm trying to display different information depending on incoming data. If it's an integer, I want to display just the number, if it's a decimal, I want to use 0.00# pattern. Ya, I know, a bit mixed up, but that's the development spec. :>

I have the following XSL for this specific section but I can't see to get past the xsl:when error message of

"Expected end of expression, found 'castable'. number(SAVG) -->castable <-- as xs:decimal"

<xsl:choose>
    <xsl:when test="number(SAVG) > 0">
        <xsl:choose>
            <xsl:when test="number(SAVG) castable as xs:decimal">
                <xsl:value-of select="format-number(SAVG, '###,###,##0.00#')"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="format-number(SAVG, '###,###,##0.###')"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:when>
    <xsl:when test="number(SAVG) = 0">
        <xsl:text disable-output-escaping="yes">&amp;lt;</xsl:text>1
    </xsl:when>
    <xsl:otherwise>N/A</xsl:otherwise>
</xsl:choose>

I tried looking/poking around for answers and I have tried "instance of", I've tried using xsl:if, etc but I can't seem to get this to work. Any help would be greatly appreciated.

Thanks.

From comments:

Yes, we are using 1.0. I'm sorry I'm new to the XSL processing, how do I glue your XSL and input to generate the html?

like image 224
PHenry Avatar asked Sep 29 '10 18:09

PHenry


1 Answers

I. XSLT 1.0:

There are no xs:integer and xs:decimal in the XPath 1.0 data model used by XSLT 1.0.

Here is a code snippet that you may use:

    <xsl:choose> 
        <xsl:when test="not(floor(SAVG) = SAVG)"> 
            <xsl:value-of select="format-number(SAVG, '###,###,##0.00#')"/> 
        </xsl:when> 
        <xsl:otherwise> <!-- Integer value -->
            <xsl:value-of select="SAVG"/> 
        </xsl:otherwise> 
    </xsl:choose> 

Do note: To test if a numeric value is an integer, we use the following test:

 floor($someNum) = $someNum

Here is one way to do this:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xsl:output method="text"/>

 <xsl:template match="/">
  <xsl:sequence select=
   "for $num in (3, 3.14)
     return
       if($num instance of xs:integer)
         then ($num, ' is xs:integer', '&#xA;')
         else if($num instance of xs:decimal)
           then ($num, ' is xs:decimal', '&#xA;')
           else ($num, ' is something else', '&#xA;')
   "/>
 </xsl:template>
</xsl:stylesheet>

when this transformation is applied on any XML document (not used), the wanted, correct result is produced:

3  is xs:integer 
3.14  is xs:decimal 

Or, using the format-number() function as per your example:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xsl:output method="text"/>

 <xsl:template match="/">
  <xsl:sequence select=
   "for $num in (3, 3.14)
     return
       if($num instance of xs:integer)
         then (format-number($num, '###,###,##0.###'), '&#xA;')
         else if($num instance of xs:decimal)
           then (format-number($num, '###,###,##0.00#'), '&#xA;')
           else ()
   "/>
 </xsl:template>
</xsl:stylesheet>

produces:

3 
3.14 
like image 154
Dimitre Novatchev Avatar answered Oct 21 '22 17:10

Dimitre Novatchev