2009-10-07 5 views
0

J'ai plusieurs <xsl:for-each/> qui s'exécutent les uns après les autres. Je voudrais, à la fin, faire quelque chose si je n'y ai pas passé. Pour seulement un for-each, je peux réussir à faire un <xsl:choose/> avec un test approprié basé sur le sélecteur dans le pour-chacun, mais pour beaucoup d'entre eux, il commence à être très moche.XSLT: comment savoir que je suis allé à l'intérieur de plusieurs pour chacun?

Quelqu'un at-il une solution pour le suivi d'un passage à travers for-each?

+0

FYI, j'ai prolongé ma réponse pour montrer comment rendre les choses plus lisibles quand vous avez beaucoup d'expressions XPath grandes et moche :-) – NickFitz

Répondre

3

En supposant que vous avez quelque chose comme:

<xsl:for-each select="foo[@bar]"> 
    <!-- do stuff for foo elements having a bar attribute --> 
</xsl:for-each> 

<xsl:for-each select="foo[@fap]"> 
    <!-- do stuff for foo elements having a fap attribute --> 
</xsl:for-each> 

vous pouvez créer l'union des nodesets sélectionnés dans chaque for-each et, si ce nodeset est vide, faire quelque chose d'autre:

<xsl:if test="not(foo[@bar] | foo[@fap])"> 
    <!-- there weren't any nodes matched above, so do something else --> 
</xsl:if> 

EDIT : Dans le cas où vos expressions XPath de sélection d'un ensemble de nœuds sont très complexes, vous pouvez rendre les choses plus faciles à suivre en utilisant des variables avec des noms significatifs; par exemple:

<xsl:variable name="articles" select="stuff/that/is[3]/very[@deeply-nested and position() &lt; 5]"/> 
<xsl:variable name="comments" select="stuff/that/is[1]/very[@deeply-nested and position() &gt; 27]"/> 
<xsl:variable name="rants" select="stuff/that/is[17]/even/more[@deeply-nested and position() &lt; 5]/with/some/more/nesting"/> 

<h1>Ramblings</h1> 

<xsl:for-each select="$articles"> 
    <!-- do stuff with articles --> 
    <h2>Article <xsl:value-of select-"position()"/></h2> 
</xsl:for-each> 

<xsl:for-each select="$comments"> 
    <!-- do stuff with comments --> 
    <h2>Comment <xsl:value-of select-"position()"/></h2> 
</xsl:for-each> 

<xsl:for-each select="$rants"> 
    <!-- do stuff with rants --> 
    <h2>Rant <xsl:value-of select-"position()"/></h2> 
</xsl:for-each> 

<xsl:if test="not($articles | $comments | $rants)"> 
    <!-- nobody had anything to say... --> 
    <h2>Nothing to see here</h2> 
</xsl:if> 
+0

Oui, c'est exactement que j'essayais d'éviter réellement ... :) Merci de toute façon. – glmxndr

+0

Par curiosité, pourquoi essayiez-vous de l'éviter? Cette utilisation des opérations set est exactement ce pour quoi XSLT/XPath a été défini :-) – NickFitz

+0

@subemed: Vous ne pouvez pas vérifier si une partie de votre script est exécutée ou non, XSLT n'est pas conçu de cette façon. Vous pouvez cependant vérifier si les * conditions * d'exécution d'une certaine partie sont remplies. Ce qui est exactement la même chose, d'un point de vue XSLT. – Tomalak

-1

Vous pouvez utiliser <xsl:variable> pour définir une variable locale selon laquelle pour chaque-vous avez saisi, puis vérifier si avec <xsl:if> à la fin.

+0

Cela ne fonctionnerait pas: la variable serait étendue à l'intérieur du for-each, et ne serait donc pas visible à l'extérieur. Une variable définie à l'extérieur ne peut pas avoir sa valeur modifiée dans le for-each. – NickFitz

+0

Nick a raison, j'ai essayé mais vous devez d'abord définir la variable, et ainsi affecter une valeur à celle-ci. Alors vous ne pouvez pas le changer, c'est inutile. – glmxndr

+0

Je suis corrigé - mon erreur. – JBRWilkinson

Questions connexes