2011-08-06 15 views
0

XMLを別のデータ構造に変換する必要があります。 私はXML以下のように受け取る:XSLTを使用してXMLノードをマージする

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

そして、私はそれがこのようなことする必要があります。

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

私はこの問題を解決するために多くの時間を費やしたが、運これまでにしました。 誰もこの問題を解決する方法を知っていますか?

+0

XSLT 1.0または2.0を使用していますか? –

答えて

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

ありがとうございます。 コードは完全に動作しています。 – Grigory

0

とテンプレートを必要としない、私はこれは古い質問ですけど、私は受け入れ答えとは違って、短い、シンプルな、一般的なプッシュ指向のデザインパターンを利用して、答えを提供したかったです複数の完全なトラバーサルは行いません。

このXSLTとき:...希望の結果が生成され

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

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

は...提供するXMLに対して実行されます

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

また、@ Mikeの答えに本質的に間違ったものは何もありませんが、これははるかにメンテナンス可能で、XSLTパーサのネイティブ機能を十分に活用しています。

関連する問題