2011-11-02 82 views
3

我有以下格式的源的xml:合併XML節點

<xml> 
    <node> 
     <va-name> 
       <source area="RSC1985s5c1"/> 
     </va-name> 
     <body> 
       <div > 
        <heading>heading 1</heading> 
       </div> 
     </body> 
    </node> 
    <node> 
     <va-name> 
       <source area="RSC1985s5c2"/> 
     </va-name> 
     <body> 
       <div > 
        <heading>heading 2</heading> 
       </div> 
     </body> 
    </node> 

    <node> 
     <va-name> 
       <source area="RSC1985s5c1"/> 
     </va-name> 
     <body> 
       <div > 
        <heading>heading 3</heading> 
       </div> 
     </body> 
    </node> 

<xml> 

我想是如果XML /節點/ VA-名稱/源[@area值是可依使用當中等於合併的節點XML /節點。我只需要複製xml/node/body並將它們合併到第一個節點中。

輸出應爲:

<xml> 
    <node> 
     <va-name> 
       <source area="RSC1985s5c1"/> 
     </va-name> 
     <body> 
       <div > 
        <heading> heading 1 </heading> 
       </div> 
       <div > 
        <heading> heading 3 </heading> 
       </div> 
     </body> 
    </node> 
    <node> 
     <va-name> 
       <source area="RSC1985s5c2"/> 
     </va-name> 
     <body> 
       <div > 
        <heading>heading 2</heading> 
       </div> 
     </body> 
    </node> 
</xml> 

在上述輸出時,節點1和節點3具有相同的XML /節點/ VA-名稱/源[@area],這就是爲什麼在i的輸出已經聯合既節點2將按原樣輸出。如果我有更多的節點,並且它們中的任何一個與節點2匹配(xml/node/va-name/source [@area]),那麼我們將它與節點2相結合,依此類推...

欣賞if我可以得到任何幫助...

+0

哪個XSLT的版本? –

回答

1

一個非常簡單的分組溶液在XSLT 2.0:

<xsl:template match="xml"> 
<xml> 
    <xsl:for-each-group select="node" group-by="va-name/source/@area"> 
    <node> 
    <xsl:copy-of select="va-name"/> 
    <body> 
     <xsl:copy-of select="current-group()/body/*"/> 
    </body> 
    </node> 
    </xsl:for-each-group> 
</xml> 
</xsl:template> 
+0

謝謝Micheal,只是修改了一點點以輸出va-name,源節點。 – atif

0

這是YAGP(又一個分組問題)使用Muenchian method最好的解決。該樣式表產生所需的輸出:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:key name="byArea" match="node" use="va-name/source/@area" /> 
    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()" /> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template 
     match="node[generate-id()= 
        generate-id(key('byArea', va-name/source/@area)[1])]"> 
     <node> 
      <xsl:apply-templates select="va-name" /> 
      <body> 
       <xsl:apply-templates select="key('byArea', va-name/source/@area)" 
        mode="out" /> 
      </body> 
     </node> 
    </xsl:template> 
    <xsl:template match="node" mode="out"> 
     <xsl:apply-templates select="body/div" /> 
    </xsl:template> 
    <xsl:template match="node" /> 
</xsl:stylesheet> 
+1

OP沒有說使用XSLT 1.0有一個限制。 2.0中的分組問題要容易得多。 –

+0

@邁克爾 - 極好的一點。也許OP可以告訴我們哪個版本的XSLT是必需的? –

+0

謝謝Lwburk,我使用的是xslt 2.0,但也嘗試過你的腳本,它的工作完美。 – atif