This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: Table generation with XSL?
- To: xsl-list at mulberrytech dot com, Chris Burn <chrislists at yahoo dot co dot uk>
- Subject: Re: Table generation with XSL?
- From: Warren Hedley <w dot hedley at auckland dot ac dot nz>
- Date: Tue, 27 Jun 2000 10:50:49 -0400
- Organization: Department of Engineering Science, The University of Auckland
- References: <004c01bfe02a$3d382080$260110ac@b2europe.com>
- Reply-To: xsl-list at mulberrytech dot com
The following stylesheet should do what you want (and
does with Saxon 5.3.2). Obviously there are some
optimisations possible - all of "match"ed templates
could be moved into the root template, for instance -
but I separated it out for clarity. Sorry, no
documentation, but I think it's pretty clear what's
going on - the key thing to note is that you have
to use recursion to implement counting functionality
in XSLT.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="Table">
<xsl:variable name="num_columns">
<xsl:call-template name="count_columns" />
</xsl:variable>
<table>
<xsl:apply-templates select="HeadRow">
<xsl:with-param name="num_columns" select="$num_columns" />
</xsl:apply-templates>
<xsl:apply-templates select="Row">
<xsl:with-param name="num_columns" select="$num_columns" />
</xsl:apply-templates>
<xsl:apply-templates select="Caption">
<xsl:with-param name="num_columns" select="$num_columns" />
</xsl:apply-templates>
</table>
</xsl:template>
<xsl:template name="count_columns">
<xsl:param name="num_columns" select="'0'" />
<xsl:param name="num_rows" select="count(HeadRow) + count(Row)" />
<xsl:param name="current_row" select="1" />
<xsl:choose>
<xsl:when test="$current_row < $num_rows">
<xsl:variable name="row" select="(HeadRow | Row)[$current_row]" />
<xsl:choose>
<xsl:when test="count($row/Cell) > $num_columns">
<xsl:call-template name="count_columns">
<xsl:with-param name="num_columns" select="count($row/Cell)" />
<xsl:with-param name="num_rows" select="$num_rows" />
<xsl:with-param name="current_row" select="$current_row + 1" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="count_columns">
<xsl:with-param name="num_columns" select="$num_columns" />
<xsl:with-param name="num_rows" select="$num_rows" />
<xsl:with-param name="current_row" select="$current_row + 1" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$num_columns" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="HeadRow">
<xsl:param name="num_columns" />
<thead>
<tr>
<xsl:for-each select="Cell">
<td><xsl:copy-of select="*|text()" /></td>
</xsl:for-each>
<xsl:call-template name="insert_blank_cells">
<xsl:with-param name="num_cells" select="$num_columns - count(Cell)" />
</xsl:call-template>
</tr>
</thead>
</xsl:template>
<xsl:template match="Row">
<xsl:param name="num_columns" />
<tr>
<xsl:for-each select="Cell">
<td><xsl:copy-of select="*|text()" /></td>
</xsl:for-each>
<xsl:call-template name="insert_blank_cells">
<xsl:with-param name="num_cells" select="$num_columns - count(Cell)" />
</xsl:call-template>
</tr>
</xsl:template>
<xsl:template match="Caption">
<xsl:param name="num_columns" />
<tr>
<td colspan="{$num_columns}"><xsl:copy-of select="*|text()" /></td>
</tr>
</xsl:template>
<xsl:template name="insert_blank_cells">
<xsl:param name="num_cells" />
<xsl:if test="$num_cells > 0">
<td><xsl:value-of select="' '" /></td>
<xsl:call-template name="insert_blank_cells">
<xsl:with-param name="num_cells" select="$num_cells - 1" />
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
--
Warren Hedley
Department of Engineering Science
Auckland University
New Zealand
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list