2013-08-29 167 views
1

我可以看到類似問題的很多答案,但我似乎無法讓他們爲我工作。我有一些xml文件,其中一些兄弟元素節點具有相同的標籤名稱。我想要使​​用XSLT合併這些節點。任何幫助將深表感謝。xslt合併具有相同名稱的多個節點

輸入:

<?xml version="1.0"?> 
<Screen> 
    <Shapes> 
    <Triangle id="tri1"> 
    <color>red</color> 
    <size>large</size> 
    </Triangle> 
    </Shapes> 
    <Shapes> 
    <Rectangle id="rec1"> 
     <color>blue</color> 
     <size>medium</size> 
    </Rectangle> 
    </Shapes> 
    <Shapes> 
    <Circle id="cir1"> 
     <color>green</color> 
     <size>small</size> 
    </Circle> 
    </Shapes> 
    <Shapes> 
    <Square id="sqr1"> 
     <color>yellow</color> 
     <size>large</size> 
    </Square> 
    </Shapes> 
    <Device> 
    <Name>peg</Name> 
    <type>X11</type> 
    </Device> 
    <Utilities> 
    <Software>QT</Software> 
    <Platform>Linux</Platform> 
    </Utilities> 
</Screen> 

我要合併所有的 「形狀」 的節點。 所需的輸出

<?xml version="1.0"?> 
<Screen> 
    <Shapes> 
    <Triangle id="tri1"> 
     <color>red</color> 
     <size>large</size> 
    </Triangle> 

    <Rectangle id="rec1"> 
     <color>blue</color> 
     <size>medium</size> 
    </Rectangle> 

    <Circle id="cir1"> 
     <color>green</color> 
     <size>small</size> 
    </Circle> 

    <Square id="sqr1"> 
     <color>yellow</color> 
     <size>large</size> 
    </Square> 
    </Shapes> 
    <Device> 
    <Name>peg</Name> 
    <type>X11</type> 
    </Device> 
    <Utilities> 
    <Software>QT</Software> 
    <Platform>Linux</Platform> 
    </Utilities> 
</Screen> 

XSLT我想是:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
version="1.0"> 
    <xsl:output indent="yes" /> 
    <xsl:template match="Shapes"> 
    <xsl:if test="not(preceding-sibling::*[local-name() = 'Shapes'])"> 

     <Shapes> 
     <xsl:apply-templates select="node() | @*" /> 
     <xsl:apply-templates select="following-sibling::*[local-name() = 'Shapes']" /> 
     </Shapes> 
    </xsl:if> 
    <xsl:if test="preceding-sibling::*[local-name() = 'Shapes']"> 
     <xsl:apply-templates select="node() | @*" /> 
    </xsl:if> 
    </xsl:template> 
    <xsl:template match="node() | @*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node() | @*" /> 
    </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

但我得到的輸出是(:()

<Screen> 
<Shapes> 
    <Triangle id="tri1"> 
     <color>red</color> 
     <size>large</size> 
    </Triangle> 

    <Rectangle id="rec1"> 
     <color>blue</color> 
     <size>medium</size> 
    </Rectangle> 

    <Circle id="cir1"> 
     <color>green</color> 
     <size>small</size> 
    </Circle> 

    <Square id="sqr1"> 
     <color>yellow</color> 
     <size>large</size> 
    </Square> 
    </Shapes> 

    <Rectangle id="rec1"> 
     <color>blue</color> 
     <size>medium</size> 
    </Rectangle> 
    <Circle id="cir1"> 
     <color>green</color> 
     <size>small</size> 
    </Circle> 
    <Square id="sqr1"> 
     <color>yellow</color> 
     <size>large</size> 
    </Square> 

    <Device> 
    <Name>peg</Name> 
    <type>X11</type> 
    </Device> 
    <Utilities> 
    <Software>QT</Software> 
    <Platform>Linux</Platform> 
    </Utilities> 
</Screen> 

有一個簡單的XSLT代碼我可以使用,還是在我的xslt中有任何修改我可以申請獲得輸出?

回答

7

這應該做的工作:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:output method="xml" indent="yes"/> 

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

    <xsl:template match="/*"> 
    <xsl:copy> 
     <Shapes> 
     <xsl:copy-of select="Shapes/*"/> 
     </Shapes> 
     <xsl:apply-templates select="*[name()!='Shapes']"/> 
    </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

的想法是要處理的Shapes所有的子元素分別一氣呵成,然後複製休息。

+0

哇...答案比我在網上看到的任何其他潛在答案都簡單和優雅,它的工作原理非常完美。沒有使用Keys /遞歸上一個或下一個兄弟電話。這真的很有幫助。非常感謝。 (還不能投票,因爲我對這個網站相當新) – Asheesh

+0

謝謝,很高興你喜歡它 – MiMo

+0

我試圖做同樣的事情,但它複製了從源到輸出的所有信息 –

相關問題