2012-10-12 6 views
1

J'essaie de créer un document XML de détail d'en-tête, défini à partir d'un autre fichier XML.Groupe XML utilisant XSLT

Source document xml:

<items> 
    <item> 
     <col1>H</col1> 
     <col2>header1</col2> 
    </item> 
    <item> 
     <col1>D</col1> 
     <col2>detail1.1</col2> 
    </item> 
    <item> 
     <col1>D</col1> 
     <col2>detail1.2</col2> 
    </item> 
    <item> 
     <col1>H</col1> 
     <col2>header2</col2> 
    </item> 
    <item> 
     <col1>D</col1> 
     <col2>detail2.1</col2> 
    </item> 
    <item> 
     <col1>D</col1> 
     <col2>detail2.2</col2> 
    </item> 
    <item> 
     <col1>D</col1> 
     <col2>detail2.3</col2> 
    </item> 
</items> 

sortie souhaitée:

<xml> 
    <transaction> 
     <items> 
      <item> 
       <col1>H</col1> 
       <col2>header1</col2> 
      </item> 
      <item> 
       <col1>D</col1> 
       <col2>detail1.1</col2> 
      </item> 
      <item> 
       <col1>D</col1> 
       <col2>detail1.2</col2> 
      </item> 
     </items> 
    </transaction> 
    <transaction> 
     <items> 
      <item> 
       <col1>H</col1> 
       <col2>header2</col2> 
      </item> 
      <item> 
       <col1>D</col1> 
       <col2>detail2.1</col2> 
      </item> 
      <item> 
       <col1>D</col1> 
       <col2>detail2.2</col2> 
      </item> 
      <item> 
       <col1>D</col1> 
       <col2>detail2.3</col2> 
      </item> 
     </items> 
    </transaction> 
</xml> 

Ma tentative XSLT:

<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/> 
    <xsl:template match="/ | node() | @* | comment() | processing-instruction()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@* | node()"/> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="item[col1='H']"> 
     <transaction> 
      <xsl:apply-templates/> 
     </transaction> 
    </xsl:template> 
</xsl:transform> 

Répondre

0

Cette transformation:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:key name="kItemByCol2Num" match="item[starts-with(col2, 'detail')]" 
    use="substring-before(substring-after(col2, 'detail'), '.')"/> 

<xsl:key name="kItemByCol2Num" match="item[starts-with(col2, 'header')]" 
    use="substring-after(col2, 'header')"/> 

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

<xsl:template match= 
"item 
    [starts-with(col2, 'header') 
    and 
    generate-id() 
    = 
    generate-id(key('kItemByCol2Num', substring-after(col2, 'header'))[1]) 
    ]"> 
    <transaction> 
    <xsl:copy-of select="key('kItemByCol2Num', substring-after(col2, 'header'))"/> 
    </transaction> 
</xsl:template> 
<xsl:template match="item"/> 
</xsl:stylesheet> 

lorsqu'il est appliqué sur le document XML fourni:

<items> 
    <item> 
     <col1>H</col1> 
     <col2>header1</col2> 
    </item> 
    <item> 
     <col1>D</col1> 
     <col2>detail1.1</col2> 
    </item> 
    <item> 
     <col1>D</col1> 
     <col2>detail1.2</col2> 
    </item> 
    <item> 
     <col1>H</col1> 
     <col2>header2</col2> 
    </item> 
    <item> 
     <col1>D</col1> 
     <col2>detail2.1</col2> 
    </item> 
    <item> 
     <col1>D</col1> 
     <col2>detail2.2</col2> 
    </item> 
    <item> 
     <col1>D</col1> 
     <col2>detail2.3</col2> 
    </item> 
</items> 

produit le résultat souhaité, correct:

<items> 
    <transaction> 
     <item> 
     <col1>H</col1> 
     <col2>header1</col2> 
     </item> 
     <item> 
     <col1>D</col1> 
     <col2>detail1.1</col2> 
     </item> 
     <item> 
     <col1>D</col1> 
     <col2>detail1.2</col2> 
     </item> 
    </transaction> 
    <transaction> 
     <item> 
     <col1>H</col1> 
     <col2>header2</col2> 
     </item> 
     <item> 
     <col1>D</col1> 
     <col2>detail2.1</col2> 
     </item> 
     <item> 
     <col1>D</col1> 
     <col2>detail2.2</col2> 
     </item> 
     <item> 
     <col1>D</col1> 
     <col2>detail2.3</col2> 
     </item> 
    </transaction> 
</items> 

Explication:

  1. Utilisation correcte de la méthode de Muenchian pour le groupement.

  2. Utilisation correcte des clés.

+0

Cela fonctionne pour le xml fourni mais mon exigence est de grouper sur col1. J'ai créé l'exemple xml avec col2 = 'header' et 'detail' juste pour que les ensembles de sortie puissent être distingués. J'essaye avec le xslt que vous avez fourni, mais puisque je ne suis pas familier avec la clef() je n'obtiens toujours pas la sortie désirée. Mon XML original a des valeurs différentes sur col2 et en fait il a plus de 20 colonnes. – gangt

+0

@gangt, la "sortie désirée" fournie * n'est pas * groupée par "col1" !!! Si vous le souhaitez, vous pouvez poser une nouvelle question - la question dans sa forme actuelle est complètement répondue. Si vous continuez à spécifier dans les nouvelles questions des données qui ne sont pas ce que vous avez en réalité, pas étonnant - les réponses seraient plutôt inutilisables. –