tags:

views:

90

answers:

2

To get "," instead of "." as a decimal point, I set the locale via setlocale("de_DE");.

When I now transform an XSLT stylesheet that contains a calculation like:

<xsl:variable name="a">
   <xsl:choose>
      <xsl:when test="$someboolean">
         <xsl:value-of select="0.5"/>
      </xsl:when>
      <xsl:otherwise>
         <xsl:value-of select="0"/>
      </xsl:otherwise>
   </xsl:choose>
</xsl:variable>
<xsl:value-of select="$a + 2"/>

returns NaN.

<xsl:value-of select="$a"/>

brings me a "0,5", which is good. But the NaN as a result of $a+2 is not what I expected.

Why is $a contverted to text? Am I doing the calculation wrong? Is this behaviour a bug?


To make myself clear. Is this the right behaviour of XSLT?

<xsl:variable name="a"><xsl:value-of select="0.5"/></xsl:variable>
<xsl:value-of select="$a"/> <!-- gives 0,5 --> 
<xsl:value-of select="$a + 2"/> <!-- gives NaN --> 
<xsl:variable name="b" select="0.5"/> 
<xsl:value-of select="$b"/> <!-- gives 0,5 --> 
<xsl:value-of select="$b + 2"/> <!-- gives 2,5 -->


The complete testing code:

<?php
printf("%.1f",0.5);  // gives 0.5
setlocale (LC_ALL, 'de_DE.utf8', 'de_DE@euro', 'de_DE', 'deu_deu', 'deu', 'de', 'ge');
printf("%.1f",0.5);  // gives 0,5

$xml = new DOMDocument;
$xml->loadXML('<a>a</a>');

$xsl = new DOMDocument;
$xsl->substituteEntities = TRUE;
$xsl->loadXML('
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
     <xsl:template match="/">
      <xsl:variable name="a"><xsl:value-of select="0.5"/></xsl:variable>
      <xsl:value-of select="$a"/>      <!-- gives 0,5 -->
      <xsl:value-of select="$a + 2"/>  <!-- gives NaN -->

      <xsl:variable name="b" select="0.5"/>
      <xsl:value-of select="$b"/>      <!-- gives 0,5 -->
      <xsl:value-of select="$b + 2"/>  <!-- gives 2,5 -->
     </xsl:template>
    </xsl:stylesheet>');

$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl);

echo $proc->transformToXML($xml);

?>
A: 

What you are mixing is output format and numerical value. The xsl expressions are not localized, therefore the decimal comma is not seen as a valid part of the value.

rsp
True, I understand now. But how do I prevent XSLT from transforming my 0.5 to 0,5?
Jan
+1  A: 

There are constructs provided in XSLT to do this:

  1. Declare a decimal-format with the "," as the decimal separator.
  2. Use the format-number function and specify the declared decimal-format.

Note: decimal-format has to be declared at the top level of the stylesheet.

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

When you want your numbers formatted with "," use format-number with the decimal-format:

<xsl:value-of select="format-number($a+2, '###.###,00', 'european')"/>
Mads Hansen
You explain how I transform a number into text. But my problem is the other way round. I have a number (select="0.5"), which is transformed automatically into a string. So that $a becomes "0,5". How do I prevent this?
Jan
Did this problem start after you switched the locale to de_DE? Do you need that locale, or were you using that to get the "," as the separator in your output? You could also try explicitly selecting that value as a number, rather than relying on the XSLT engine to "duck type" it: <xsl:value-of select="number('0.5')"/>
Mads Hansen
I switched the locae because of other PHP stuff. That this changes something inside XSLT was not wat I wanted.Using number() does not help.
Jan
I'm having trouble reproducing that behavior. Maybe you could replace the "." with "," and see if it evaluates as a number? translate(0.5, '.',',')
Mads Hansen
If I enter "0,5" instead of "0.5" I get an error, since "0,5" is not a number nor a string in XPath. If I enter "'0,5'" I also get an error, since XPath is not able to parse the string.
Jan
Thanks for posting the full example. I think your problem is that the value assigned to $a is being evaluated a string instead of a number, since you are calling value-of.From the spec: "The xsl:value-of element is instantiated to create a text node in the result tree. The required select attribute is an expression; this expression is evaluated and the resulting object is converted to a string as if by a call to the string function. The string specifies the string-value of the created text node" http://www.w3.org/TR/xslt#value-of
Mads Hansen