2017-08-22 4 views
0

Mon XML contient deux éléments de liste. En cours d'exécution sur la première boucle, j'ai besoin d'exécuter la boucle sur le 2ème élément dans la première boucle. Pouvez-vous m'aider à ce sujet?Boucle dans XSLT pour deux listes indépendantes

Ci-dessous mon exemple XML

<?xml version="1.0" encoding="UTF-8"?> 
    <Data> 
     <Object> 
      <ID>123</ID> 
      <List> 
      <ListItem> 
       <ReferenceToObject>123</ReferenceToObject> 
       <Name>ABC</Name> 
      </ListItem> 
      <ListItem> 
       <ReferenceToObject>345</ReferenceToObject> 
       <Name>CDE</Name> 
      </ListItem> 
      <ListItem> 
       <ReferenceToObject>456</ReferenceToObject> 
       <Name>EFG</Name> 
      </ListItem> 
      </List> 
      <Line> 
      <LineItem> 
       <ReferenceToObject>123</ReferenceToObject> 
       <LineName>ABCD</LineName> 
      </LineItem> 
      <LineItem> 
       <ReferenceToObject>345</ReferenceToObject> 
       <LineName>CDEF</LineName> 
      </LineItem> 
      <LineItem> 
       <ReferenceToObject>456</ReferenceToObject> 
       <LineName>EFGH</LineName> 
      </LineItem> 
      </Line> 
     </Object> 
    </Data> 

While running on the first loop i would like to include the elements in the list list where in i can match it using ReferenceToObject. 

The output i want is like below 

<Data> 
    <Object> 
     <ID>123</ID> 
     <List> 
     <ListItem> 
      <ReferenceToObject>123</ReferenceToObject> 
      <Name>ABC</Name> 
      <LineName>ABCD</LineName> 
     </ListItem> 
     <ListItem> 
      <ReferenceToObject>345</ReferenceToObject> 
      <Name>CDE</Name> 
      <LineName>CDEF</LineName> 
     </ListItem> 
     <ListItem> 
      <ReferenceToObject>456</ReferenceToObject> 
      <Name>EFG</Name> 
      <LineName>EFGH</LineName> 
     </ListItem> 
     </List> 
</Object> 
</Data> 

Je suis en cours d'exécution pour une boucle sur le premier élément dans cette boucle que je veux exécuter une autre boucle pour le copier et le noms de ligne champ referenceToObject correspondant.

concernant

+0

Montrez-nous le code que vous visitez ntly ont avec le résultat que vous obtenez actuellement et le résultat que vous voulez atteindre. Comme vous avez étiqueté la question comme [tag: xslt-grouping] et [tag: xslt-2.0] en utilisant https://www.w3.org/TR/xslt20/#xsl-for-each-group semble évident –

+0

Merci @ Martin, mis à jour le poste avec la sortie désirée et l'approche suivie – NKT

+0

Eh bien, donner un essai https://www.w3.org/TR/xslt20/#xsl-for-each-group, il y a même des exemples dans la spécification à https://www.w3.org/TR/xslt20/#grouping-examples. –

Répondre

0

Vous pouvez utiliser pour-chaque groupe pour que:

XSLT 2,0

<?xml version="1.0" encoding="UTF-8"?> 
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
     <xsl:template match="List"> 
      <xsl:copy> 
       <xsl:for-each-group select="//ListItem|//LineItem" group-by="ReferenceToObject"> 
        <ListItem> 
         <xsl:copy-of select="ReferenceToObject"/> 
         <xsl:copy-of select="current-group()/Name"/> 
         <xsl:copy-of select="current-group()/LineName"/> 
        </ListItem> 
       </xsl:for-each-group> 
      </xsl:copy> 
     </xsl:template> 

     <xsl:template match="Line"/> 

<!-- Identity Transformation --> 
     <xsl:template match="@*|node()"> 
      <xsl:copy> 
       <xsl:apply-templates select="@*|node()"/> 
      </xsl:copy> 
     </xsl:template> 
    </xsl:stylesheet> 

Dans XSLT 1.0-vous gérer cela avec clé

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:key name="refobject" match="LineItem" use="ReferenceToObject"/> 

    <xsl:template match="List"> 
     <xsl:copy> 
      <xsl:for-each select="ListItem"> 
       <xsl:copy> 
        <xsl:copy-of select="child::*"/> 
        <xsl:variable name="currentobj" select="normalize-space(ReferenceToObject)"/> 
        <xsl:copy-of select="key('refobject', $currentobj)/LineName"/> 
       </xsl:copy> 
      </xsl:for-each> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="Line"/> 

    <!-- Identity Transformation --> 
    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet>