2009-01-17 7 views
20

J'imbriqué xsl: pour les boucles:Comment accéder aux éléments de la boucle externe depuis des boucles imbriquées?

<xsl:for-each select="/Root/A"> 
    <xsl:for-each select="/Root/B"> 
     <!-- Code --> 
    </xsl:for> 
</xsl:for> 

intérieur de la boucle intérieure, comment puis-je accéder aux attributs du noeud courant dans la boucle extérieure?

Je continue à me trouver un code écrit comme ceci:

<xsl:for-each select="/Root/A"> 
    <xsl:variable name="someattribute" select="@SomeAttribute"/> 
    <xsl:for-each select="/Root/B"> 
     <!-- Now can use $someattribute to access data from 'A' --> 
    </xsl:for> 
</xsl:for> 

Cela fait très bien, car parfois échelle ne ai pas besoin d'accéder à plusieurs éléments d'information et finissent par créer une variable pour chaque pièce. Y a-t-il un moyen plus facile?

Répondre

26

Vous pouvez stocker la structure/Root/A entière dans une variable et faire référence à cette variable plutôt que de créer une nouvelle variable pour chaque attribut et sous-élément auquel vous devez accéder.

<xsl:for-each select="/Root/A/"> 
    <xsl:variable name="ROOT_A" select="."/> 
    <xsl:for-each select="/Root/B/"> 
     <!-- Variable is accessed like this: $ROOT_A/@someAttribute 
       Just like a normal XML node --> 
    </xsl:for-each> 
</xsl:for-each> 
+0

+1, mais il pourrait être utile de modifier le nom variable pour rendre sa fonction plus claire . – AnthonyWJones

+0

Terminé. Merci pour la contribution. – Welbog

+0

C'est ce que je finis habituellement par faire ;-p –

8

Welbog a répondu bien - mais juste pour vous noter semblez faire une cartesion (croix) JOIN - est-ce intentionnel? Si vous essayez de faire une jointure normale (avec un prédicat, etc.), alors vous voulez voulez regarder dans <xsl:key/> - à savoir Déclarez une clé:

<xsl:key name="BIndex" match="/Root/B" use="SomeChildNode"/> 

consommera dans votre prédicat:

<xsl:for-each select="/Root/A/"> 
    <xsl:variable name="ROOT_A" select="."/> 
    <xsl:for-each select="key('BIndex', LocalNode)"> 
    <!-- --> 
    </xsl:for-each> 
</xsl:for-each> 

Cela devrait être équivalent à (mais beaucoup plus rapide que) le prédicat:

<xsl:for-each select="/Root/B[SomeChildNode = current()/LocalNode]"> 

Si vous êtes groupant les données, puis regardez Muenchian grouping

+0

Merci pour les conseils .. Je suis relativement nouveau à XSLT et ne suis pas complètement sûr de ce que je fais pour le moment. Une fois que tout fonctionne, je vais regarder ce que vous suggérez de voir s'il y a un moyen plus simple. – pauldoo

+0

Note: Il m'a fallu un peu d'effort pour déchiffrer la partie «jointure cartésienne-prédicat-jointure» ci-dessus. Il suffit donc de noter la différence pour les nouveaux utilisateurs. Fondamentalement, si vous avez un nombre m de noeuds dans A et n nombre de noeuds dans B, la jointure cartésienne se traduira par m * n nœuds alors que jointure de prédicat jointes sur une clé particulière, à savoir joindre A et B où A. clé = B.key. – GuruM

+0

Pour vérifier le nom de l'élément current (l'élément que la boucle forte itère), vous pouvez utiliser 'name (current())' - ne pas essayer 'current()/name()', ce n'est pas autorisé. – CoDEmanX

0

Ce qui suit pourrait également être utilisé:

<xsl:for-each select="ns:attribute"> 
     <name><xsl:value-of select="ns:name" /></name>    
     <xsl:for-each select="ns:value"> 
     <value><xsl:value-of select="."/></value>  
     </xsl:for-each> 
    </xsl:for-each>  

Pour l'analyse du document XML ..

<ns:attribute> 
     <ns:name>name</ns:name> 
     <!--1 or more repetitions:--> 
     <ns:value>Rahul</ns:value> 
     <ns:value>Sushovan</ns:value> 
</ns:attribute> 
Questions connexes