web-dev-qa-db-fra.com

Comment rompre une boucle for-each en XSLT?

Comment rompre une boucle for-each en XSLT?

19
Daniel Silveira

XSLT est écrit dans un style très fonctionnel, et dans ce style il n'y a pas d'équivalent d'une instruction break. Ce que vous pouvez faire est quelque chose comme ceci:

<xsl:for-each select="...nodes...">
    <xsl:if test="...some condition...">
        ...body of loop...
    </xsl:if>
</xsl:for-each>

De cette façon, le for-each continuera à parcourir tous les nœuds, mais le corps de la boucle ne sera exécuté que si la condition est vraie.

28
Greg Hewgill

Mettez la condition d'arrêt de la "boucle" dans l'attribut select du for-each élément. Par exemple, pour "casser" après quatre éléments:

<xsl:for-each select="nodes[position()&lt;=4]">

Pour itérer jusqu'à mais sans inclure un nœud qui remplissait une condition particulière:

<xsl:for-each select="preceding-sibling::node[condition]">
17
user663031

XSLT n'est pas un langage procédural; ne pensez pas que for-each soit une "boucle" dans la façon dont vous avez une boucle en Java. For-each est un moyen d'appliquer un modèle à chacun des éléments. Cela ne se produit pas nécessairement dans un ordre particulier, vous ne pouvez donc pas le considérer comme "appliquer ce modèle à chacun des éléments jusqu'à ce que tel ou tel se produise, puis arrêter".

Cela dit, vous pouvez utiliser l'attribut select pour filtrer les résultats, il ressemble donc plus à "appliquer un modèle à chacun des éléments, mais uniquement si tel ou tel est vrai d'eux".

Si ce que vous voulez vraiment, c'est "appliquer un modèle à chacun des éléments, où tel ou tel est vrai d'eux, mais seulement au premier c'est vrai", vous pouvez combiner l'attribut select avec la position () fonction.

8
Jacob Mattison

Une "rupture" du corps d'un <xsl:for-each> L'instruction XSLT ne peut pas être spécifiée à l'aide d'une construction syntaxique , cependant elle peut être simulée.

Cet extrait de code sur topxml.com décrit la technique en détail:

Dans le cas où vous avez besoin d'un "" break "" d'une boucle xsl: for-each

Essentiellement deux techniques sont discutées :

  1. Effectuer quelque chose à l'intérieur du corps de <xsl:for-each> uniquement si une condition spécifique est remplie.

  2. Spécification du traitement n'utilisant pas <xsl:for-each> mais avec récursivité

La deuxième méthode a l'avantage de pouvoir effectuer la sortie immédiatement , contrairement à la première méthode qui doit encore effectuer de nombreux "cycles vides" même après la la condition de sortie a été satisfaite.

4
Dimitre Novatchev

J'ai eu une situation similaire et voici le code que j'avais écrit. Pour des raisons logiques, je ne pouvais pas entrer dans les autres conditions avec condition01.

<xsl:for-each select="msxsl:node-set($DATA6)[condition01]"> 
<xsl:choose>
<xsl:when test="not((condtion02 or  condition03) and condition04)">
--body of for loop 
</xsl:when>
</xsl:choose>
</xsl:for-each>
0
rjose

Bonjour, je sais que c'est un ancien article, mais il peut peut-être aider d'autres développeurs. J'ai trouvé un moyen de casser un pour chacun en XSLT ce n'est pas littéralement une pause mais si vous voyez le code, vous l'obtiendrez. Comme vous le savez ou pas, vous pouvez utiliser du code C # en ligne dans xslt. Dans cet exemple, je veux boucler tous les nœuds et prendre le premier nœud NTE avec Value RC Mais si j'obtiens un nœud qui diffère du nœud NTE, je veux arrêter de regarder la condition. J'ai donc mis une variable globale en code C # et je demande la valeur à chaque fois que je passe par un nœud:

    <xsl:value-of select="userCSharp:SetStopForeach('true')" />
<xsl:for-each select="following-sibling::node()">

        <xsl:if test="local-name()='NTE_NotesAndComments_3' and userCSharp:GetStopForeach()" >

        <xsl:for-each select="NTE_4_CommentType">
            <xsl:if test="(CE_0364_0_IdentifierSt)[text()=&quot;RC&quot;]"> 
        <ns0:RESULTAAT_COMMENTAAR>
                    <xsl:for-each select="../NTE_3_Comment">

                        <xsl:value-of select="./text()" />
                    </xsl:for-each>
                </ns0:RESULTAAT_COMMENTAAR> 
            </xsl:if>
        </xsl:for-each>
        </xsl:if>
        <xsl:if test="local-name()='ORC_CommonOrder'" >
            <xsl:value-of select="userCSharp:SetStopForeach('false')" />
        </xsl:if>
    </xsl:for-each>


    .....

    <msxsl:script language="C#" implements-prefix="userCSharp">
 <![CDATA[ 

    public bool StopForeach=false;
    public bool GetStopForeach() {
        return StopForeach;
    }
    public string SetStopForeach(bool aValue) {
         StopForeach=aValue;
         return "";
    }

      ]]> 
      </msxsl:script>
0
orophine