delsanic
delsanic

Reputation: 777

How to transform xml data into rows and columns?

Here is my input XML:

<data>
    <node>1</node>
    <node>2</node>
    <node>3</node>
    <node>4</node>
    <node>5</node>
    <node>6</node>
    <node>7</node>
    <node>8</node>
</data>

Required HTML output table:

row = 2

1 | 3 | 5 | 7
2 | 4 | 6 | 8

row = 3

1 | 4 | 7
2 | 5 | 8
3 | 6 | 

XSLT-1.0: ??

How do i transform the above xml to the above structure in html. The number of rows is not predefined and will be provided as a parameter.

Upvotes: 0

Views: 723

Answers (2)

Ian Roberts
Ian Roberts

Reputation: 122414

Given the list of nodes

<xsl:variable name="nodes" select="/data/node"/>

you need to create one row for each of the first n nodes

<xsl:for-each select="$nodes[position() &lt;= $numRows]">
  <xsl:variable name="rowNum" select="position()"/>
  <tr>

Then within the row the cells can be selected by modulo arithmetic - the first row is node 1, n+1, 2n+1 etc, the second row is 2, n+2, ...

    <xsl:for-each select="$nodes[position() mod $numRows = $rowNum]">

Edit: as pointed out in the comments this won't work for the last row - you need to change the definition of rowNum to be modulo numRows too:

  <xsl:variable name="rowNum" select="position() mod $numRows"/>

because the modulo value for the last row is 0 rather than n.

Upvotes: 0

michael.hor257k
michael.hor257k

Reputation: 117165

Try it this way:

<xsl:variable name="rows" select="2" />

<xsl:template match="/data">
    <table>
            <xsl:for-each select="node[position() &lt;= $rows]">
                <xsl:variable name="i" select="position() mod $rows"/>
                <tr>
                    <xsl:for-each select="../node[position() mod $rows = $i]">
                        <td><xsl:value-of select="."/></td>
                    </xsl:for-each>
                </tr>
            </xsl:for-each>
    </table>
</xsl:template>

Upvotes: 2

Related Questions