2010-02-18 89 views
3

我有下面的代码。在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> 

回答

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)" /> 
+0

做了诡计,谢谢 – 2010-02-19 09:11:21

0

没有因为XSLT是不是程序语言,声明是这样说的并行方式运行,同时让所有的数据,然后显示它。所以它没有迭代知识。

+0

不是非常有建设性的。 – AxelEckenberger 2010-02-18 17:52:30

0

那么你不能在xlst中退出for循环(see link)。因此,您必须以不同的方式对其进行处理:

  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> 
    

+0

但据我所知,这些选项都不能让我能够对xml中的项目进行排序,如果我错了,请纠正我的错误? – 2010-02-18 17:59:37

+0

也许这可能会帮助你进一步http://stackoverflow.com/questions/1643621/xsl-recursive-sort/1645790。虽然,我可以看到它可能会使事情复杂化。所以我担心没有简单的解决方案。一般来说,可以说,如果你需要循环休息,你将不得不以某种方式使用递归。您也可以查看http://www.dpawson.co.uk/xsl/sect2/sect21.html,看看是否有更多关于您的具体问题。 – AxelEckenberger 2010-02-18 18:07:29

0

你能不能把条件选择表达式的谓语,在换使用位置每个,如下所示:

<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>