2013-06-24 55 views
3

我有這樣滯留在XSLT 2.0分組

<items> 
    <item> 
     <id>5</id> 
     <name>Harry</name> 
     <age>18</age> 
     <color>blue</color> 
    </item> 
    <item> 
     <id>5</id> 
     <name>Harry</name> 
     <age>18</age> 
     <fav_food>pizza</fav_food> 
    </item> 
    <item> 
     <id>5</id> 
     <name>Harry</name> 
     <age>18</age> 
     <is_single>true</is_single> 
    </item> 
</items> 

我想組最多的元素,使文件看起來像這樣

<items> 
<item> 
    <id>5</id> 
    <name>Harry</name> 
    <age>18</age> 
    <color>blue</color> 
    <fav_food>pizza</fav_food> 
    <is_single>true</is_single> 
</item> 
</items> 

編輯輸入文件 - 一個製造按照此鏈接進行XSLT轉換(XSLT Consolidating data when ID is the same),但這只是不打印任何東西。

這裏是我的變換(使用XSLT 2.0) -

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

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

<xsl:template match="item"> 
    <xsl:apply-templates select="@*" /> 
    <xsl:for-each-group select="item" group-by="id"> 
    <item> 
     <id><xsl:value-of select="current-grouping-key()"/></id> 
     <xsl:apply-templates select="current-group()" /> 
    </item> 
    </xsl:for-each-group> 
</xsl:template> 

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

<xsl:template match="*"> 
    <xsl:element name="{local-name()}"> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:element> 
</xsl:template> 

</xsl:stylesheet> 
+0

如果使用XSLT 2.0,您可以用'的for-each-group' - 退房[這個問題]的答案(http://stackoverflow.com/q/11247326/1395993),這是一個類似的問題。 –

+0

XSLT 1.0和2.0中的分組非常不同,你真的需要說出你正在使用的是哪一個。 –

+0

對不起,我忘記說,我使用XSLT 2.0,並更新了我現在有XSLT轉換我的問題。 – Narabhut

回答

1

你的主要問題是你有一個模板項目元件匹配:

<xsl:template match="item"> 

但在此,你有xsl:for-each-group也尋找item elements

<xsl:for-each-group select="item" group-by="id"> 

這意味着,你正在尋找項目元素是其他項目元素,其中有沒有在XML的孩子。我認爲你需要前兩個模板合併成一個位置:

說不清楚
<xsl:template match="items"> 
    <xsl:for-each-group select="item" group-by="id"> 
     <item> 
      .... 

的一件事是什麼項目中的元素元素將被重複。它會永遠是身份證,名稱和年齡嗎?儘管這裏可能最好是靈活的,並且假設只有id將是常見元素。我還會假設如果兩個元素重複(如名稱)它將始終具有相同的值。

因此,要獲得所有其他不同的非ID的元素,你可以多一些上進行分組元素名稱

<xsl:for-each-group select="current-group()/*[not(self::id)]" group-by="local-name()"> 

然後,在這個循環中,你可以只輸出的元素。

試試這個XSLT

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

<xsl:template match="items"> 
    <xsl:for-each-group select="item" group-by="id"> 
    <item> 
     <id><xsl:value-of select="current-grouping-key()"/></id> 
     <xsl:for-each-group select="current-group()/*[not(self::id)]" group-by="local-name()"> 
     <xsl:apply-templates select="self::*" /> 
     </xsl:for-each-group> 
    </item> 
    </xsl:for-each-group> 
</xsl:template> 

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

<xsl:template match="*"> 
    <xsl:element name="{local-name()}"> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:element> 
</xsl:template> 

</xsl:stylesheet> 

當適用於您的XML,下面是輸出

<item> 
    <id>5</id> 
    <name>Harry</name> 
    <age>18</age> 
    <color>blue</color> 
    <fav_food>pizza</fav_food> 
    <is_single>true</is_single> 
</item> 
+0

這工作完美。非常感謝,我欣賞詳細的解釋! – Narabhut