我是XSL的新手,面临着使用相同名称对xml元素进行分组的问题。 这是我的输入xml元素
<Products>
<Product type='Item' id='111'>
<Group1>
<color>Blue</color>
<item>xxx</item>
</Group1>
<Group1>
<color>Green</color>
<item>yyy</item>
</Group1>
<Group2>
<color>Yellow</color>
<item>xxx</item>
</Group2>
<Group2>
<color>White</color>
<item>yyy</item>
</Group2>
<Product type='ChildItem'>
<Group1>
<color>Blue</color>
<item>xxx</item>
</Group1>
<Group1>
<color>Green</color>
<item>yyy</item>
</Group1>
<Group2>
<color>Yellow</color>
<item>xxx</item>
</Group2>
<Group2>
<color>White</color>
<item>yyy</item>
</Group2>
</Product>
</Product>
<Product type='Item' id='222'>
<Group1>
<color>Blue</color>
<item>xxx</item>
</Group1>
<Group1>
<color>Green</color>
<item>yyy</item>
</Group1>
<Group2>
<color>Yellow</color>
<item>xxx</item>
</Group2>
<Group2>
<color>White</color>
<item>yyy</item>
</Group2>
<Product type='ChildItem'>
<Group1>
<color>Blue</color>
<item>xxx</item>
</Group1>
<Group1>
<color>Green</color>
<item>yyy</item>
</Group1>
<Group2>
<color>Yellow</color>
<item>xxx</item>
</Group2>
<Group2>
<color>White</color>
<item>yyy</item>
</Group2>
</Product>
</Products>
我们正试图获得如下输出:
<Products>
<Product type='Item' id='111'>
<Group1>
<color>Blue</color>
<item>xxx</item>
<color>Green</color>
<item>yyy</item>
</Group1>
<Group2>
<color>Yellow</color>
<item>xxx</item>
<color>White</color>
<item>yyy</item>
</Group2>
<Product type='ChildItem'>
<Group1>
<color>Blue</color>
<item>xxx</item>
<color>Green</color>
<item>yyy</item>
</Group1>
<Group2>
<color>Yellow</color>
<item>xxx</item>
<color>White</color>
<item>yyy</item>
</Group2>
</Product>
</Product>
<Product type='Item' id='222'>
<Group1>
<color>Blue</color>
<item>xxx</item>
<color>Green</color>
<item>yyy</item>
</Group1>
<Group2>
<color>Yellow</color>
<item>xxx</item>
<color>White</color>
<item>yyy</item>
</Group2>
<Product type='ChildItem'>
<Group1>
<color>Blue</color>
<item>xxx</item>
<color>Green</color>
<item>yyy</item>
</Group1>
<Group2>
<color>Yellow</color>
<item>xxx</item>
<color>White</color>
<item>yyy</item>
</Group2>
</Product>
</Product>
</Products>
我使用下面的xsl文件进行转换,但未按预期获得输出
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="elements" match="/Product/*" use="name()"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<xsl:copy>
<xsl:for-each select="*[count(. | key('elements', name())[1]) = 1]">
<xsl:copy>
<xsl:apply-templates select="key('elements', name())/*"/>
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:1)
您要按名称对Product
的子元素进行分组,但是这个分组需要针对每个产品单独进行,因此您需要引用Product
是关键用法
<xsl:key name="elements"
match="Product/*[not(self::Product)]"
use="concat(name(), '|', generate-id(..))"/>
注意密钥匹配如何没有/
前缀,否则它只匹配一个名为Product
的根元素,它在您的情况下不会匹配。还要注意它是如何仅与非Product
元素匹配的。
(也不是使用generate-id()
为Product
元素生成一个唯一ID来识别它?
接下来,您需要更改第二个模板以匹配Product
,而不是\*
,因为\*
仅匹配根元素。然后在此模板中,您将获得如下所示的分组元素:
<xsl:for-each
select="*[generate-id() = generate-id(key('elements', concat(name(), '|', generate-id(..)))[1])]">
试试这个XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="elements" match="Product/*[not(self::Product)]" use="concat(name(), '|', generate-id(..))"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Product">
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:for-each select="*[generate-id() = generate-id(key('elements', concat(name(), '|', generate-id(..)))[1])]">
<xsl:copy>
<xsl:apply-templates select="key('elements', concat(name(), '|', generate-id(..)))/*"/>
</xsl:copy>
</xsl:for-each>
<xsl:apply-templates select="Product" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>