Re: [xsl] how do i implement a WHILE like function

Subject: Re: [xsl] how do i implement a WHILE like function
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Sun, 4 Mar 2001 12:14:29 +0000
Hi Vinh,

> I have a list of results that can be 100 rows long, with 25 lines
> per page which equals 4 pages. Now, the server passes to me only 25
> rows at a time and also passes to me the total number pages (4) and
> the current page.
[snip]
> Page (2 or 4)   1  2  3  4        (each number in this row a link)
>
> How do I do this? I was thinking of passing parameters to a template
> recursively or using the known number of rows to do a for-each and
> increment a counter variable (but this limits the number of pages to
> the total number of rows on the page).

So the problem is that because the total number of pages might vary,
the footer might vary accordingly?  Presumably you don't know what the
maximum number of pages might be, or are there always going to be 4 or
less?

If there are always going to be 4 or less, then you could just do
something like:

  <a href="...">1</a>
  <xsl:if test="$total &gt; 1">
     <a href="...">2</a>
     <xsl:if test="$total &gt; 2">
        <a href="...">3</a>
        <xsl:if test="$total &gt; 3">
           <a href="...">4</a>
        </xsl:if>
     </xsl:if>
  </xsl:if>

but for true flexibility, you either need a recursive solution,
something like:

<xsl:template name="link">
   <xsl:param name="page" select="1" />
   <a href="..."><xsl:value-of select="$page" /></a>
   <xsl:if test="$page &lt; $total">
      <xsl:call-template name="link">
         <xsl:with-param name="page" select="$page + 1" />
      </xsl:call-template>
   </xsl:if>
</xsl:template>

Or you could use an xsl:for-each using the Piez method.  Collect a
large number of nodes and then use only the first N where N is the
total:

   <xsl:for-each select="$nodes[position() &lt;= $total]">
      <a href="..."><xsl:value-of select="position()" /></a>
   </xsl:for-each>

One way of getting a large number of nodes is to gather the nodes
within the stylesheet itself:

<xsl:variable name="nodes" select="document('')//node()" />

If you need more, you can add namespace nodes and attribute nodes to
the collection, which should at least double it:

<xsl:variable name="nodes" select="document('')//node() |
                                   document('')//namespace::* |
                                   document('')//@*" />

I hope that helps,

Jeni

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



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


Current Thread