Reputation: 671
I have the code below. I would the for-each to stop running after the if-sentenses have returned true and executed the code block 4 times. As i have no idea when the code block has been executed 4 times i can't use position() which was my first idea.
Any help would be greatly appreciated.
<xsl:for-each select="$itm//item[@template='news item']">
<xsl:sort select="sc:fld('start date',.)" data-type="text" order="descending"/>
<xsl:if test="sc:formatdate($date,'yyyyMMddHHmm') > sc:formatdate(sc:fld('start date',.),'yyyyMMddHHmm')">
<xsl:if test="sc:formatdate($date,'yyyyMMddHHmm') < sc:formatdate(sc:fld('end date',.),'yyyyMMddHHmm')">
<!--EXECUTE A CODE BLOCK-->
</xsl:if>
</xsl:if>
</xsl:for-each>
Upvotes: 3
Views: 1450
Reputation: 167716
Can't you put the conditions in a predicate of the select expression and the use position in the for-each, as follows:
<xsl:for-each select="$itm//item[@template='news item'][sc:formatdate($date,'yyyyMMddHHmm') > sc:formatdate(sc:fld('start date',.),'yyyyMMddHHmm')][sc:formatdate($date,'yyyyMMddHHmm') < sc:formatdate(sc:fld('end date',.),'yyyyMMddHHmm')]">
<xsl:sort select="sc:fld('start date',.)" data-type="text" order="descending"/>
<xsl:if test="position() < 5">
<!-- output something -->
</xsl:if>
</xsl:for-each>
Upvotes: 0
Reputation: 338406
<!-- convenience variables -->
<xsl:variable name="dtFormat" select="'yyyyMMddHHmm'" />
<xsl:variable name="theDate" select="sc:formatdate($date, $dtFormat)" />
<!-- don't loop over nodes testing a condition on each one separately,
just select the interesting ones directly -->
<xsl:variable name="MatchingFields" select="
$itm//item[@template='news item'][
sc:formatdate(sc:fld('start date', .), $dtFormat) < $theDate
and
sc:formatdate(sc:fld('end date', .), $dtFormat) > $theDate
]
" />
<!-- now do something with the nodes -->
<xsl:for-each select="$MatchingFields">
<xsl:sort select="sc:fld('start date',.)" data-type="text" order="descending"/>
<!--EXECUTE A CODE BLOCK-->
</xsl:for-each>
<!-- you can also count them (this is your "hit counter") -->
<xsl:value-of select="count($MatchingFields)" />
Upvotes: 1
Reputation: 16936
Well you cannot "exit" a for loop in xlst (see link). So you will have to to at it in a different way:
Use recursion (using call-template or apply-template and a parameter passsed into the template with with-param). On each recursion you can increment the parameter if the code block was executed prior to passing it to the next recursion level. You have to check whether the parameter is equal to 4 before you are entering the next recursion level (i.e. the exit condition for the recursive function).
<!-- exit condition -->
<xsl:if test="$executed < 4">
<!-- check conditions and select next item -->
<xsl:choose>
<!-- condition for items where the code should be executed -->
<xsl:when test="test whether code should be executed">
<!-- execute your code here -->
<xsl:apply-templates select="select next item" mode="recursive">
<xsl:with-param name="executed" select="$executed + 1"/>
</xsl:apply-templates>
</xsl:when>
<!-- condition for items where the code should not be executed -->
<xsl:otherwise>
<xsl:apply-templates select="select next item" mode="recursive">
<xsl:with-param name="executed" select="$executed"/>
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
Upvotes: 0
Reputation: 6612
No because xslt is not a procedural language, the statement is so to speak running in a parallel way, getting all the data simultaneously and then displaying it. so it has no knowledge of iteration.
Upvotes: 0