2009-01-17 30 views
20

he anidado XSL: para bucles:¿Cómo accedo a los elementos desde el bucle externo desde dentro de los bucles anidados?

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

Desde dentro del bucle interno, ¿cómo puedo acceder a los atributos del nodo actual en el bucle externo?

sigo encontrando a mí mismo escribiendo código como este:

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

Esto no escala muy bien, ya que a veces necesito para acceder a varias piezas de información y terminar creando una variable para cada pieza. hay una manera mas facil?

Respuesta

26

Puede almacenar toda la estructura/Root/A en una variable y hacer referencia a esa variable en lugar de crear una nueva variable para cada atributo y subelemento al que necesite acceder.

<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, pero podría valer la pena editar el nombre de la variable para hacer más clara su función . – AnthonyWJones

+0

Hecho. Gracias por el aporte. – Welbog

+0

Eso es lo que generalmente termino haciendo ;-p –

8

Welbog ha respondido bien - pero sólo para señalar que parecen estar haciendo un cartesion (cruz) se une a - es intencional? Si usted está tratando de hacer un habitual unirse (con un predicado, etc), entonces usted quiere que desee ver en <xsl:key/> - es decir, declarar una clave:

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

luego consumen en su predicado:

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

esto debe ser equivalente a (pero mucho más rápido que) el predicado:

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

Si está agrupar los datos, y luego mirar Muenchian grouping

+0

Gracias por los consejos .. Soy relativamente nuevo en XSLT y aún no estoy completamente seguro de lo que estoy haciendo. Una vez que las cosas funcionen, echaré un vistazo a lo que sugieres para ver si hay una manera más fácil. – pauldoo

+0

Nota: me costó un poco de esfuerzo descifrar la parte de unión cartesiana vs. parte predicado-unión anterior. Así que solo anote la diferencia para las personas que son nuevas en ella. Básicamente si tiene una 'm' cantidad de nodos en A y 'n' cantidad de nodos en B, cartesian join dará como resultado m * n nodos mientras que predicate-join se une a una clave particular, es decir, join A AND B donde A. clave = B.key. – GuruM

+0

Para verificar el nombre del elemento de la corriente (el elemento que for-loop itera), puede usar 'name (current())' - no intente 'current()/name()', no está permitido. – CoDEmanX

0

Lo siguiente también se podría utilizar:

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

Para analizar el documento XML ..

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