计算for-each中的“命中数”

时间:2010-02-18 17:01:11

标签: xslt foreach

我有以下代码。在if-sentenses返回true并执行代码块4次之后,我会让for-each停止运行。因为我不知道代码块何时被执行了4次我不能使用position()这是我的第一个想法。

非常感谢任何帮助。

<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') &gt; sc:formatdate(sc:fld('start date',.),'yyyyMMddHHmm')">
        <xsl:if test="sc:formatdate($date,'yyyyMMddHHmm') &lt; sc:formatdate(sc:fld('end date',.),'yyyyMMddHHmm')">
    <!--EXECUTE A CODE BLOCK-->
        </xsl:if>
    </xsl:if>
</xsl:for-each>

4 个答案:

答案 0 :(得分:1)

<!-- 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) &lt; $theDate
    and
    sc:formatdate(sc:fld('end date', .), $dtFormat) &gt; $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)" />

答案 1 :(得分:0)

不,因为xslt不是一种过程语言,所以该语句可以并行运行,同时获取所有数据然后显示它。所以它不知道迭代。

答案 2 :(得分:0)

嗯,你不能在xlst(see link)中“退出”for循环。所以你必须以不同的方式去做它:

  1. 更改select语句,以便for-each仅迭代您要执行代码的四个项目。
  2. 使用递归(使用call-template或apply-template以及使用with-param传递到模板中的参数)。在每次递归时,如果在将代码块传递到下一个递归级别之前执行了代码块,则可以递增参数。在输入下一个递归级别(即递归函数的退出条件)之前,必须检查参数是否等于4。

        

        

    <!-- exit condition -->
    <xsl:if test="$executed &lt; 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>
    

答案 3 :(得分:0)

你不能把条件放在选择表达式的谓词和for-each中的使用位置,如下所示:

<xsl:for-each select="$itm//item[@template='news item'][sc:formatdate($date,'yyyyMMddHHmm') &gt; sc:formatdate(sc:fld('start date',.),'yyyyMMddHHmm')][sc:formatdate($date,'yyyyMMddHHmm') &lt; sc:formatdate(sc:fld('end date',.),'yyyyMMddHHmm')]">
    <xsl:sort select="sc:fld('start date',.)" data-type="text" order="descending"/>
    <xsl:if test="position() &lt; 5">
      <!-- output something -->
    </xsl:if>
</xsl:for-each>