Comment rompre une boucle for-each en XSLT?
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.
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()<=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]">
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.
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 :
Effectuer quelque chose à l'intérieur du corps de <xsl:for-each>
uniquement si une condition spécifique est remplie.
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.
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>
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()="RC"]">
<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>