My input XML document is a simple list of items. The number of items is arbitrary:
<items>
<item name="item1"/>
<item name="item2"/>
<item name="item3"/>
...
<item name="itemX"/>
</items>
Now, I want to split this list into HTML tables. The number of rows and columns are given as parameter values:
<xsl:param name="rows"/>
<xsl:param name="cols"/>
If we let rows be 3, and cols be 2, the resulting HTML should look like:
<table>
<tr>
<td>item1</td>
<td>item2</td>
</tr>
<tr>
<td>item3</td>
<td>item4</td>
</tr>
<tr>
<td>item5</td>
<td>item6</td>
</tr>
</table>
<table>
<tr>
<td>item7</td>
<td>item8</td>
</tr>
<tr>
<td>item9</td>
<td>item10</td>
</tr>
<tr>
<td>item11</td>
<td>item12</td>
</tr>
</table>
...
The number of <table>s created is thus ceil(number_of_items / rows / cols)
I have a basic idea how to solve this, but I can’t seem to get the last tweaks right. The following stylesheet produces something close to what I want, but item 4, 7, 10 and 13 are duplicated.
Does anyone have a better idea about how to do this?
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="cols" select="2"/>
<xsl:param name="rows" select="3"/>
<xsl:template match="/*">
<html>
<head/>
<body>
<xsl:apply-templates select="*[position() mod ($cols * $rows) = 1]" mode="table"/>
</body>
</html>
</xsl:template>
<xsl:template match="*" mode="table">
<table border="1" id="{@name}">
<xsl:apply-templates select="." mode="row"/>
<xsl:apply-templates select="following-sibling::*[position() > 1 and position() mod $rows = 0]" mode="row"/>
</table>
</xsl:template>
<xsl:template match="*" mode="row">
<tr id="{@name}">
<xsl:apply-templates select="." mode="cell"/>
<xsl:apply-templates select="following-sibling::*[position() < $cols]" mode="cell"/>
</tr>
</xsl:template>
<xsl:template match="*" mode="cell">
<td>
<xsl:apply-templates select="."/>
</td>
</xsl:template>
<xsl:template match="item">
<xsl:value-of select="@name"/>
</xsl:template>
</xsl:stylesheet>
You can try to add +1 to $cols like this:
Try this for the table template (you have to limit the amount of items per table):