2010-02-18 4 views
3

J'ai le code ci-dessous. Je voudrais que chacun arrête de s'exécuter après que les if-sentenses soient retournés vrais et ait exécuté le bloc de code 4 fois. Comme je n'ai aucune idée quand le bloc de code a été exécuté 4 fois je ne peux pas utiliser position() qui était ma première idée.Comptage du nombre de 'hits' dans pour chaque

Toute aide serait grandement appréciée.

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

Répondre

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

qui a fait l'affaire, merci –

0

Non, parce que xslt est pas une langue de procédure, la déclaration est pour ainsi dire en cours d'exécution d'une manière parallèle, obtenir toutes les données simultanément, puis l'afficher. donc il n'a aucune connaissance de l'itération.

+0

Pas très constructif. – AxelEckenberger

0

Eh bien, vous ne pouvez pas "quitter" une boucle for dans xlst (see link). Vous devrez donc le faire d'une manière différente:

  1. Modifiez l'instruction select de sorte que chaque itération ne réponde que sur les quatre éléments pour lesquels vous voulez exécuter votre code.
  2. Utilisez la récursivité (en utilisant call-template ou apply-template et un paramètre passé dans le modèle avec -param). Sur chaque récursion, vous pouvez incrémenter le paramètre si le bloc de code a été exécuté avant de le passer au niveau de récursivité suivant. Vous devez vérifier si le paramètre est égal à 4 avant d'entrer dans le niveau de récurrence suivant (c'est-à-dire la condition de sortie pour la fonction récursive).

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

Mais pour autant que je sache aucune de ces options me donne la possibilité de trier les éléments dans le xml, corrigez-moi si je me trompe? –

+0

Peut-être que cela pourrait vous aider davantage http://stackoverflow.com/questions/1643621/xsl-recursive-sort/1645790. Bien que, je peux voir que cela pourrait compliquer les choses. Donc je crains qu'il n'y ait pas de solution facile. En général, on peut dire que si vous avez besoin de faire une boucle avec une pause, vous devrez utiliser la récursion d'une manière ou d'une autre. Vous pouvez également regarder http://www.dpawson.co.uk/xsl/sect2/sect21.html pour voir s'il y a plus sur votre problème spécifique. – AxelEckenberger

0

Ne peut pas vous mettre les conditions dans un prédicat de l'expression de sélection et la position d'utilisation dans le lucratif chacun, comme suit:

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