[xsl] Split a string and fill it in a table (xslt1.0)

Subject: [xsl] Split a string and fill it in a table (xslt1.0)
From: christoph.naber@xxxxxxxxxxxxxxxxxxx
Date: Fri, 17 Aug 2007 11:18:32 +0200
Hello list,

(XSLT 1.0, afaik MSXML (I dont use the stylesheets, they are included in
some visual basic programs))
I wonder about whats a good way to split a string at whitespaces and fill
it into a table which has four rows and four columns. The string contains
a transformation-matrix and for better visualization I have to put it into
a html-table.

I know how to split strings, but how do I put them in rows each with four
cells? I cannot use extensionfunctions like node-set which would IMHO make
things much easier.

The example input XML:

<root>
        <transform>12 34 1 5 54 2 6 24 34 34 6 23 67 234 74.45
2</transform>
</root>

Desired output:
<table>
        <tr>
                <td>12</td>
                <td>34</td>
                <td>1</td>
                <td>5</td>
        </tr>
        <tr>
                <td>54</td>
                <td>2</td>
                <td>6</td>
                <td>24</td>
        </tr>
        <tr>
                <td>34</td>
                <td>34</td>
                <td>6</td>
                <td>23</td>
        </tr>
        <tr>
                <td>67</td>
                <td>234</td>
                <td>74.45</td>
                <td>2</td>
        </tr>
</table>

I have a working solution, but I like to know if there is a better way to
do this.

Here is my stylesheet:

<xsl:template match="transform">
        <table>
                <xsl:call-template name="row">
                        <xsl:with-param name="string" select="text()" />
                </xsl:call-template>
        </table>
</xsl:template>

<!-- create a row and pass the string to the element template. recursive
call the row-template with the already used elements chopped off as long
as string contains whitespaces -->
<xsl:template name="row">
        <xsl:param name="string" select="string('')" />
        <xsl:variable name="shorter">
                <xsl:call-template name="eater">
                        <xsl:with-param name="string" select="$string" />
                </xsl:call-template>
        </xsl:variable>

        <xsl:if test="contains($string, ' ')">
                <tr>
                        <xsl:call-template name="element">
                                <xsl:with-param name="string"
select="$string" />
                        </xsl:call-template>
                </tr>
                <xsl:if test="contains($shorter, ' ')" >
                        <xsl:call-template name="row">
                                <xsl:with-param name="string"
select="$shorter" />
                        </xsl:call-template>
                </xsl:if>
        </xsl:if>

</xsl:template>

<!-- create 4 cells by recursive calls to the element-template -->
<xsl:template name="element">
        <xsl:param name="string" select="string('')" />
        <xsl:param name="count" select="0" />

        <xsl:choose>
                <!-- when 3 cells are done, output the last element in the
row and no recursive call -->
                <xsl:when test="$count > 2 and contains($string, ' ')">
                        <td><xsl:value-of
select="substring-before($string, ' ')" /></td>
                </xsl:when>

                <!-- output the last element in the string when $string
contains no more whitespaces -->
                <xsl:when test="not(contains($string, ' '))">
                        <td><xsl:value-of select="$string" /></td>
                </xsl:when>

                <!-- output the next element and recursive call the
element template with the shortened string -->
                <xsl:otherwise>
                        <td><xsl:value-of
select="substring-before($string, ' ')" /></td>
                        <xsl:call-template name="element">
                                <xsl:with-param name="string"
select="substring-after($string, ' ')" />
                                <xsl:with-param name="count"
select="$count + 1" />
                        </xsl:call-template>
                </xsl:otherwise>
        </xsl:choose>
</xsl:template>

<!-- "eat" 4 elements at the beginning of the string -->
<xsl:template name="eater" >
        <xsl:param name="string" select="string('')" />
        <xsl:value-of
select="substring-after(substring-after(substring-after(substring-after($stri
ng,
' '), ' '), ' '), ' ')" />
</xsl:template>

Greetings Christoph



If you are not the intended addressee, please inform us immediately that you
have received this e-mail by mistake and delete it. We thank you for your
support.

Current Thread