Search code examples
xmlxsltstring-formattingnumber-formattinginteger-arithmetic

XSLT Tokenize output as numbers


In the following code:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="input">
    <xsl:variable name="n" select="tokenize(./text(),'[0-9]+([,.][0-9]+)?')"/>
    <xsl:choose>
        <xsl:when test="(($n[0]*$n[0]+$n[1]*$n[1])/(n[3]*($n[0]*$n[0]+$n[1]*$n[1])))>300">
            Retina!
        </xsl:when>
        <xsl:otherwise>
            Trash!
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>
</xsl:stylesheet>

Example input:

<input>1920 1400 0.425</input>

I use tokenize to match some numbers in between two input tags. The only problem is that resulting list of numbers are all formatted as strings, and so fail the maths later in the code.

So, is there a way to get tokenizer to output a list of numbers, or alternatively is there an equivalent of map in XSLT 2.0?

Note: I am using the Saxon processor


Solution

  • is there a way to get tokenizer to output a list of numbers

    Yes. For example, you could do:

    <xsl:variable name="n" select="for $i in tokenize($input, $pattern) return number($i)"/>
    

    Note, however that:

    1. Your tokenizing pattern does not return the expected values;
    2. In XPath, nodes are numbered from 1; $n[0] is empty and any numerical operation using it will result in NaN.