Splitting single column data into multiple column HTML tables

On the ASP.NET message boards, dorsai78664 asks how to create a multi-column table with single column data using XSLT. Given the input XML document:

<root>

 <ComputerName value ="ComputerA" />

 <ComputerName value ="ComputerB" />

 <ComputerName value ="ComputerC" />

 <ComputerName value ="ComputerD" />

 <ComputerName value ="ComputerE" />

 <ComputerName value ="ComputerF" />

 <ComputerName value ="ComputerG" />

 <ComputerName value ="ComputerH" />

 <ComputerName value ="ComputerI" />

 <ComputerName value ="ComputerJ" />

 </root>

 

Dorsai wanted to output this as an HTML table with each row containing only 6 columns.  The key is that the position() function is relative to the current node set. The pointer to the node (the context) is defined in the for-each select statement, so the first node selected is that with position = 1. The first tr is added to the result tree, and the current node (".") and its following 5 sibling nodes are selected and applied to the attribute template. This means that nodes 1-6 are selected in the first loop iteration. The mod() operation then selects node 7, because it is the next one where mod 6 = 1. The loop selects the current node ("."), which is node 7, and its following 5 sibling nodes, selecting 7-12 and applying the template.

<xsl:stylesheet version ="1.0" xmlns:xsl ="**https://www.w3.org/1999/XSL/Transform**" >

<xsl:template match =" / " >

<html>

<table>

<xsl:for-each select =" /root/ComputerName[position() mod 6 = 1] " >

 <xsl:sort select =" @value" order ="ascending" />

<tr>

 <xsl:apply-templates select =" ./@value | following-sibling::ComputerName[position() < 6]/@value" />

 </tr>

 </xsl:for-each>

 </table>

 </html>

 </xsl:template>

<xsl:template match =" @value" >

<td class ="normal" >

 <xsl:value-of select =" . " />

 </td>

 </xsl:template>

 </xsl:stylesheet>

The result is:

<html>

<table>

<tr>

 <td class ="normal" >ComputerA</td>

 <td class ="normal" >ComputerB</td>

 <td class ="normal" >ComputerC</td>

 <td class ="normal" >ComputerD</td>

 <td class ="normal" >ComputerE</td>

 <td class ="normal" >ComputerF</td>

 </tr>

<tr>

 <td class ="normal" >ComputerG</td>

 <td class ="normal" >ComputerH</td>

 <td class ="normal" >ComputerI</td>

 <td class ="normal" >ComputerJ</td>

 </tr>

 </table>

 </html>