2011-08-06 143 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解析器的本地功能。