Re: [xsl] ordering and iteration problem

Subject: Re: [xsl] ordering and iteration problem
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Wed, 2 May 2001 09:31:27 +0100
Wendell wrote:
> Mark:
> At 06:44 PM 5/1/01, you wrote:
>>I'm curious why one typically initializes "random-nodes" from the
>>stylesheet document rather than the input document.  It seems to me
>>that the input document is guaranteed to have enough nodes, while the
>>XSLT transform document might not if the input document is big enough.
>>
>>Instead of
>>
>>     <xsl:variable name="random-nodes" select="document('')//node()" />
>>
>>I tried
>>
>>     <xsl:variable name="random-nodes" select="//node()" />
>>
>>to get the set of all nodes from the input document.  This seems to
>>work for me.  I was wondering if there is any reason why this is not
>>what is typically done.

[snip]
> The only thing to be careful about is to make sure you have *enough*
> nodes, which is why this iteration workaround (which of course fails
> without any warning if your node set falls short) is kind of scuzzy
> compared to a proper solution using recursion.
[snip]

> (Jeni, what's your perspective?)

The main reason I use nodes from the stylesheet is because that set of
nodes will remain constant until you change the stylesheet - you have
a predictable set - it's either going to have more than 100 nodes in
it or less than a 100 nodes in it. So if you know that you need to
iterate up to 100 times, no matter what the source XML looks like,
then it's beneficial to have a node set you *know* will be (at least)
that size.

The set of random nodes should be tailored to the number of times you
need to iterate.  I use the following sets:

  document('')//*
  document('')//node()
  document('')//node() | document('')//@*
  document('')//node() | document('')//@* | document('')//namespace::*

The other advantage, as Wendell said, is that it drums home the point
that they're random nodes - you really don't care about what they are
or where they come from.
  
If you *do* care, or if the number of times that you're iterating is
dependent on the size of the source XML in any way then you should be
using nodes from the source XML. If you want to iterate the same
number of times as you have nodes of type X, then you should be
iterating over that set of nodes. If you want to iterate twice that
amount, then have a nested xsl:for-each and iterate over them twice.

In particular, you should *never* be using the Piez method to get a
counter that you use in a positional predicate in the same node set
each time, like:

  <xsl:for-each
        select="$random-nodes[position() &lt;= count($my-nodes)]">
     <xsl:apply-templates select="$my-nodes[position()]" />
  </xsl:for-each>

Which gives exactly the same result (but in a very roundabout way) to:

  <xsl:for-each select="$my-nodes">
     <xsl:apply-templates select="." />
  </xsl:for-each>

(which itself is probably better as <xsl:apply-templates
select="$my-nodes"/>, but that's not important right now).

Cheers,

Jeni

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



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


Current Thread