Generating HTML tables with XSLT

The following code snippet is a relatively simple and reusable implementation for generating HTML table content.

    <!-- The number of columns in the generated table -->
    <xsl:variable name="nColumns" select="3" />

    <!--
        XPath indexes start at 1, not 0. 'row' and 'column' template
        parameters therefore default to 1
    -->
    
    <xsl:template name="tableRows">
        <!-- The table content node list -->
        <xsl:param name="items" />
        <!-- The current row index -->
        <xsl:param name="row" select="1" />
        <!--
            Calculate the total number of rows based on the number of
            items and the number of columns
        -->
        <xsl:variable name="nRows" select="ceiling(count($items) div $nColumns)"></xsl:variable>
        <xsl:element name="tr">
            <xsl:call-template name="tableColumns">
                <xsl:with-param name="items" select="$items" />
                <xsl:with-param name="row" select="$row" />
            </xsl:call-template>
        </xsl:element>
         <!--
              There's no loop construct in XSLT so we simply increment
              the row index and call the template again if the current
              row index is less than the total number of rows
         -->
        <xsl:if test="$nRows > $row">
            <xsl:call-template name="tableRows">
                <xsl:with-param name="items" select="$items" />
                <xsl:with-param name="row" select="$row + 1" />
            </xsl:call-template>
        </xsl:if>
    </xsl:template>

    <xsl:template name="tableColumns">
        <!-- The table content node list -->
        <xsl:param name="items" />
        <!-- The current row index -->
        <xsl:param name="row" />
        <!-- The current column index -->
        <xsl:param name="column" select="1" />
        <!--
            Calculate the item index based on the current row and
            column index
        -->
        <xsl:variable name="itemIndex" select="(($row - 1) * $nColumns) + $column" />
        <xsl:element name="td">
            <!-- Check the item index is 'in bounds' -->
            <xsl:if test="count($items) >= $itemIndex">
                <xsl:call-template name="tableCellContent">
                    <xsl:with-param name="item" select="$items[$itemIndex]" />
                </xsl:call-template>
            </xsl:if>
        </xsl:element>
         <!--
              There's no loop construct in XSLT so we simply increment
              the column index and call the template again if the current
              column index is less than the specified number of columns
         -->
        <xsl:if test="$nColumns > $column">
            <xsl:call-template name="tableColumns">
                <xsl:with-param name="items" select="$items" />
                <xsl:with-param name="row" select="$row" />
                <xsl:with-param name="column" select="$column + 1" />
            </xsl:call-template>
        </xsl:if>
    </xsl:template>

    <xsl:template name="tableCellContent">
        <xsl:param name="item" />
        <!-- Generate content for the current item -->
        ...
    </xsl:template>
Advertisements
Tagged with: , , ,
Posted in XSLT

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: