views:

46

answers:

1

I am having a problem where the value of the $current variable came in as '6E144270003'. My original goal was to just test for a number, but '6E144270003' passed the number() test because it is a valid 'scientific notation' (as was pointed out to me here).

I need a valid test to allow data containing only integers (can include the decimal and minus sign) to equate to true and any other data to equate to false.

Should pass: 1234567890
Should pass: 123.45
Should pass: 123.5
Should pass: -123.45

 <xsl:if test="number($current) = number($current)">  
    <xsl:value-of select="$current"/>   
 </xsl:if>  
+2  A: 

I am having a problem where the value of the $current variable came in as '6E144270003' and it failed in the Saxon 2.0 processor with an error of 'Cast failed, invalid lexical value - xs:double'.

I cannot repro this problem.

This transformation:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
 <xsl:variable name="current" select="'6E144270003'"/>
    <xsl:template match="/">
    <xsl:if test="number($current) = number($current)">
    <xsl:value-of select="$current"/>
 </xsl:if>

    </xsl:template>
</xsl:stylesheet>

when run with SAXON 9.0.0.4, produces:

6E144270003

I'm unsure why this happened when it is not a number and also how to correct it. Basically if it is not a number I don't want to output it

The string "6E144270003" can be used as a number in XPath 2.0, because in XPath 2.0 the so called *scientific notation` is a valid way to represent a number.

This is one interesting example where the behavior of XSLT 1.0 and XSLT 2.0 is different.

UPDATE: The OP has indicated that he wants a test that will evaluate to false() if the string contains anything but digits.

This can be achieved best by a regular expression, or even:

translate($s, '0123456789', '') eq ''

UPDATE2: The OP changed his question again!!!

For the latest question here is the answer:

Use:

$s castable as xs:decimal

This transformation demonstrates the correctness of this method:

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

    <xsl:template match="/">
     <xsl:sequence select=
      "for $s in ('1234567890',
                 '123.45',
                 '123.5',
                '-123.45',
                 '6E144270003'
                 )
       return
         if($s castable as xs:decimal)
           then $s
           else ()

      "/>
    </xsl:template>
</xsl:stylesheet>

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

1234567890 123.45 123.5 -123.45
Dimitre Novatchev
@Dimitre: +1 fast answer. Also this is the same for me. I think it should point out that this is not the proper data type test in XSLT 2.0. The OP should use 'castable' operator.
Alejandro
@Alejandro: `castable` is useful to test if some `item()` is of a certain type. If the OP is just interested if a value *can be represented and used as a number* then `number($x) = number($x)` is still a good test.
Dimitre Novatchev
In this case the data will not ever be represented as a 'scientific notation'. I need the IF condition in this case to fail due to the 'E'.
johkar
@jonkar: This is even a valid integer! So, please, update your question and say that you want to test that all characters of the string are digits!
Dimitre Novatchev
@jonkar: I updated my answer, giving you a solution that you probably want.
Dimitre Novatchev
@Dimitre: The question has changed again...
Alejandro
@jonkar: I updated my answer for a second time to answer your *new* question!!! Please, don't change your question!!! `ASK NEW QUESTIONS !!!`
Dimitre Novatchev
@Alejandro: Thanks, I edited my answer -- we might ask SO to automatically downvote questions that change more than twice.
Dimitre Novatchev
I am sorry Dimitre and Alejandro, I edited my question because I thought that was what Dimitri was asking me several comments up. I do appreciate your patience and guidance and will strive to get it right next time.
johkar