Search code examples
arraysxsltsaxonxslt-3.0xpath-3.1

XSL output array of string as text


I am trying to create an array and append few values to it and output the transformed text by iterating over this array. But the output is ignoring the content of xsl:text.

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:fn="http://www.w3.org/2005/xpath-functions"
    xmlns:map="http://www.w3.org/2005/xpath-functions/map"
    xmlns:array="http://www.w3.org/2005/xpath-functions/array"
    version="3.0">
    <xsl:strip-space elements="*" />
    <xsl:template name="test" match="/">
        <xsl:param name="data" select="data"></xsl:param>
        <xsl:variable name="myData" select="$data" />

        <xsl:variable name="myArray" as="array(xs:string)">
            <xsl:sequence select="array{}" />
        </xsl:variable>
        <xsl:sequence select="array:append($myArray, 'John')" />
        <xsl:sequence select="array:append($myArray, 'Peter')" />

        <xsl:for-each select="1 to array:size($myArray)">
            <xsl:text>Person name is : </xsl:text>
            <xsl:value-of select="array:get($myArray,.)" />
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>
              

This output as

["John"]
["Peter"]

While I was expecting

Person name is : John
Person name is : Peter

Solution

  • I believe that the main problem with your attempt is that the instruction:

    <xsl:sequence select="array:append($myArray, 'John')" />
    

    does not modify the $myArray variable. It merely writes to the output the result of appending a member to the (empty) array in $myArray, while the size of the array itself remains 0.

    If instead you use:

    <xsl:variable name="myArray" select="array:append($myArray, 'John')" />
    

    and:

    <xsl:variable name="myArray" select="array:append($myArray, 'Peter')" />
    

    you should get the result you seek.


    BTW, you can shorten:

        <xsl:variable name="myArray" as="array(xs:string)">
            <xsl:sequence select="array{}" />
        </xsl:variable>
    

    to:

    <xsl:variable name="myArray" select="array{}"/>
    

    P.S. A purist will tell you that in my suggestion the original $myArray variable is also not being modified; it is only shadowed by binding another value to the same name.