2011-08-06 7 views
0

J'ai besoin de transformer mon XML en une autre structure de données. je reçois le XML comme ci-dessous:Fusionner des nœuds XML en utilisant XSLT

<results> 
    <resultset> 
    <result> 
     <name>BMW Cars</name> 
     <code>BMW Pkw</code> 
     <model.model>730d Saloon</model.model> 
     <model.name>KM21</model.name> 
    </result> 
    <result> 
     <name>BMW Cars</name> 
     <code>BMW Pkw</code> 
     <model.model>120i 3 doors</model.model> 
     <model.name>UA51</model.name> 
    </result> 
    <result> 
     <name>BMW Cars</name> 
     <code>BMW Pkw</code> 
     <model.model>Z4 sDrive23i</model.model> 
     <model.name>LM31</model.name> 
    </result> 
    <result> 
     <name>Audi</name> 
     <code>AUDI</code> 
     <model.model>A4 SAL.3.0 Q SPT TIP 5SPD</model.model> 
     <model.name>8E2SFZ04</model.name> 
    </result> 
    <result> 
     <name>Audi</name> 
     <code>AUDI</code> 
     <model.model>A6 SAL. 2.5TDI SPORT MAN.6SP.</model.model> 
     <model.name>4B2BBC04</model.name> 
    </result> 
    <result> 
     <name>AUdi</name> 
     <code>AUDI</code> 
     <model.model>A8 4.2 QUATTRO 6-SPD TIP</model.model> 
     <model.name>4E201L04</model.name> 
    </result> 
    </resultset> 
</results> 

Et je besoin d'être comme ceci:

<results> 
    <resultset> 
    <result> 
     <name>BMW Cars</name> 
     <code>BMW Pkw</code> 
     <model.model>730d Saloon</model.model> 
     <model.name>KM21</model.name> 
     <model.model>120i 3 doors</model.model> 
     <model.name>UA51</model.name> 
     <model.model>Z4 sDrive23i</model.model> 
     <model.name>LM31</model.name> 
    </result> 
    <result> 
     <name>Audi</name> 
     <code>AUDI</code> 
     <model.model>A4 SAL.3.0 Q SPT TIP 5SPD</model.model> 
     <model.name>8E2SFZ04</model.name> 
     <model.model>A6 SAL. 2.5TDI SPORT MAN.6SP.</model.model> 
     <model.name>4B2BBC04</model.name> 
     <model.model>A8 4.2 QUATTRO 6-SPD TIP</model.model> 
     <model.name>4E201L04</model.name> 
    </result> 
    </resultset> 
</results> 

J'ai passé beaucoup de temps pour résoudre ce problème, mais pas de chance jusqu'à présent. Est-ce que quelqu'un sait comment résoudre ce problème?

+0

Utilisez-vous XSLT 1.0 ou 2.0? –

Répondre

1
<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes" /> 

<xsl:key name="groupName" match="//results/resultset/result" use="concat(name, code)" /> 

<xsl:template match="/"> 

    <results> 
    <resultset> 
    <xsl:for-each select="//results/resultset/result[generate-id() = generate-id(key('groupName', concat(name, code)) [1]) ]" > 


     <xsl:call-template name="group"> 
     <xsl:with-param name="k1" select="name" /> 
     <xsl:with-param name="k2" select="code" /> 
     </xsl:call-template> 

    </xsl:for-each> 

    </resultset> 
    </results> 
</xsl:template> 

<xsl:template name="group"> 
<xsl:param name="k1" /> 
<xsl:param name="k2" /> 

    <result> 
     <xsl:copy-of select="name" />  
     <xsl:copy-of select="code" />  

     <xsl:for-each select="//results/resultset/result[name = $k1][code = $k2]"> 

     <xsl:copy-of select="model.model" />  
     <xsl:copy-of select="model.name" />  

     </xsl:for-each> 
    </result> 

</xsl:template> 
</xsl:stylesheet> 
+0

Merci beaucoup. Votre code fonctionne parfaitement. – Grigory

0

Je sais que cette question est plus, mais je voulais fournir une réponse qui, contrairement à la réponse acceptée, est plus courte, plus simple, utilise des modèles de conception orientée enfichables communes, ne nécessite pas de modèles avec paramètres, et ne fait pas plusieurs traversées complètes de l'arbre.

Lorsque cette XSLT:

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

    <xsl:key name="kResultByNameCode" match="result" use="concat(name, '+', code)"/> 

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

    <xsl:template match="result[generate-id() = generate-id(key('kResultByNameCode', concat(name, '+', code))[1])]"> 
    <xsl:copy> 
     <xsl:apply-templates select="name | code"/> 
     <xsl:apply-templates select="key('kResultByNameCode', concat(name, '+', code))/*[starts-with(name(), 'model')]"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="result"/> 

</xsl:stylesheet> 

... est exécuté sur le XML fourni:

<?xml version="1.0" encoding="UTF-8"?> 
<results> 
    <resultset> 
    <result> 
     <name>BMW Cars</name> 
     <code>BMW Pkw</code> 
     <model.model>730d Saloon</model.model> 
     <model.name>KM21</model.name> 
    </result> 
    <result> 
     <name>BMW Cars</name> 
     <code>BMW Pkw</code> 
     <model.model>120i 3 doors</model.model> 
     <model.name>UA51</model.name> 
    </result> 
    <result> 
     <name>BMW Cars</name> 
     <code>BMW Pkw</code> 
     <model.model>Z4 sDrive23i</model.model> 
     <model.name>LM31</model.name> 
    </result> 
    <result> 
     <name>Audi</name> 
     <code>AUDI</code> 
     <model.model>A4 SAL.3.0 Q SPT TIP 5SPD</model.model> 
     <model.name>8E2SFZ04</model.name> 
    </result> 
    <result> 
     <name>Audi</name> 
     <code>AUDI</code> 
     <model.model>A6 SAL. 2.5TDI SPORT MAN.6SP.</model.model> 
     <model.name>4B2BBC04</model.name> 
    </result> 
    <result> 
     <name>Audi</name> 
     <code>AUDI</code> 
     <model.model>A8 4.2 QUATTRO 6-SPD TIP</model.model> 
     <model.name>4E201L04</model.name> 
    </result> 
    </resultset> 
</results> 

... le résultat recherché est produit:

<results> 
    <resultset> 
    <result> 
     <name>BMW Cars</name> 
     <code>BMW Pkw</code> 
     <model.model>730d Saloon</model.model> 
     <model.name>KM21</model.name> 
     <model.model>120i 3 doors</model.model> 
     <model.name>UA51</model.name> 
     <model.model>Z4 sDrive23i</model.model> 
     <model.name>LM31</model.name> 
    </result> 
    <result> 
     <name>Audi</name> 
     <code>AUDI</code> 
     <model.model>A4 SAL.3.0 Q SPT TIP 5SPD</model.model> 
     <model.name>8E2SFZ04</model.name> 
     <model.model>A6 SAL. 2.5TDI SPORT MAN.6SP.</model.model> 
     <model.name>4B2BBC04</model.name> 
     <model.model>A8 4.2 QUATTRO 6-SPD TIP</model.model> 
     <model.name>4E201L04</model.name> 
    </result> 
    </resultset> 
</results> 

Encore une fois, rien de fondamentalement faux avec la réponse de @ Mike, mais c'est beaucoup plus maintenable et fait une utilisation plus complète des capacités natives de l'analyseur XSLT.

Questions connexes