[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] Mods and Looping


Subject: Re: [xsl] Mods and Looping
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Mon, 10 Jun 2002 14:07:09 +0100

Hi Gary,

> I have been writing a template which allows me to process columns of
> content blocks in HTML across the page at different modulus. It
> works fine but I would very much like to use a loop to optimise the
> code and apply a blocks at any modulus, can anyone give me any
> pointers on how I go about doing this? The template that I think
> needs a loop is the following code (I also wonder at what point it
> would be more efficient to write a loop, how many mod!)...

I think that you need to have a separate recursive template that
creates the requisite cells, given a certain fixed modulus, a fixed
set of nodes, a fixed padding, and a changing count:

<xsl:template name="create-cells">
  <xsl:param name="mod" select="1" />
  <xsl:param name="nodes" select="image" />
  <xsl:param name="padding" select="3" />
  <xsl:param name="count" select="1" />
  ...
</xsl:template>

The template always needs to create a cell for the current count,
holding the nodes whose position mod $mod is the same as $count (mod
$mod):

<xsl:template name="create-cells">
  <xsl:param name="mod" select="1" />
  <xsl:param name="nodes" select="image" />
  <xsl:param name="padding" select="3" />
  <xsl:param name="count" select="1" />
  <td valign="top">
    <xsl:apply-templates
      select="$nodes[position() mod $mod = $count mod $mod]" />
  </td>
  ...
</xsl:template>

It only needs to recurse if $count is less than $mod; it recurses by
adding 1 to the count. If you are recursing, you need to add the
separator cell as well, as follows:

<xsl:template name="create-cells">
  <xsl:param name="mod" select="1" />
  <xsl:param name="nodes" select="image" />
  <xsl:param name="padding" select="3" />
  <xsl:param name="count" select="1" />
  <td valign="top">
    <xsl:apply-templates
      select="$nodes[position() mod $mod = $count mod $mod]" />
  </td>
  <xsl:if test="$count &lt; $mod">
    <td>
      <xsl:call-template name="spacer">
        <xsl:with-param name="width" select="$padding + 2" />
      </xsl:call-template>
    </td>
    <xsl:call-template name="create-cell">
      <xsl:with-param name="mod" select="$mod" />
      <xsl:with-param name="nodes" select="$nodes" />
      <xsl:with-param name="padding" select="$padding" />
      <xsl:with-param name="count" select="$count + 1" />
    </xsl:call-template>
  </xsl:if>
</xsl:template>

You should call this template from your 'mod' template as follows:

<xsl:template name="mod">
  <xsl:param name="padding" select="3" />
  <xsl:param name="number" select="1" />
  <xsl:param name="node" select="image"/>
  <table xsl:use-attribute-sets="table.0">
    <tr>
      <xsl:call-template name="create-cells">
        <xsl:with-param name="mod" select="$number" />
        <xsl:with-param name="nodes" select="$node" />
        <xsl:with-param name="padding" select="$padding" />
      </xsl:call-template>
    </tr>
  </table>
</xsl:template>

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list



Current Thread