David Carlisle
> Now imagine that when the conditions are such that <xsl:otherwise> is
> matched, one wants to break out of the <xsl:for-each>.
It is hard to imagine that because the template instantiated
for each node selected by the xsl:for-each has no side
effects and so any test that means that you do not want to
evaluate the template on some node could have been done
before the xsl:for-each.
You only need select the nodes that you want, you don't need
to select all of the nodes and then try to `break' the loop.
It is best to think of xsl:for-each evaluating the template
on all the nodes _at the same time_. Some xslt engines may
in fact evaluate them one at a time, in document order, but
they are not obliged to do that.
You can of course implement a while loop using a recursive
named template rather than xsl:for-each.
Chris Maden adds
Thinking words like "while" and "until" will get you into
trouble with XSLT. Try to rephrase the question: "do this
if it's before the first foo where not bar". For example ,
let's say you have a list of <foo> siblings. One of them
has a bar attribute; you only want the <foo>s before the
first bar.
<xsl:apply-templates select="foo[following-siblings::*[@bar]]"/> will only select the <foo>s who have a following sibling
with a bar attribute.
Nikolai Grigoriev adds
> Imagine,
> <xsl:for-each select="foo">
> <xsl:choose>
> <xsl:when test="bar">blah</xsl:when>
> <xsl:otherwise>blort</xsl:otherwise>
> </xsl:choose>
> </xsl:for-each>
>
> Now imagine that when the conditions are such that <xsl:otherwise> is
> matched, one wants to break out of the <xsl:for-each>.
>
How about this:
<!-- Identify the stopper - the first node that does not have a bar -->
<xsl:variable name="stop-id" select="generate-id(foo[not(bar)][1])"/>
<!-- Segregate nodes preceding the stopper -->
<xsl:for-each select="foo">
<xsl:if test="following-sibling::foo[generate-id() = $stop-id]">
blah
</xsl:if>
</xsl:for-each>
This is simple but suspicious from the efficiency point of view.
I suspect that the recursive solution is more economic.
|