xslt组在父节点以及子节点下的相同节点
问题描述:
我想在父标记(<Item>
)以及子标记(<Sku>
)中对具有相同名称的节点进行分组。xslt组在父节点以及子节点下的相同节点
<Item>
标签可能包含许多<Sku>
子标签,但这些不应该在每一个Sku
进行分组,而元素和Item
应单独分组。
我有一个输入XML文件,如下图所示:
<Products>
<Item>
<Dimensions>
<Height>10</Height>
</Dimensions>
<Dimensions>
<Weight>10</Weight>
</Dimensions>
<Color>
<Attribute>Orange</Attribute>
</Color>
<Color>
<Attribute>Blue</Attribute>
</Color>
<Sku>
<Dimensions>
<Height>10</Height>
</Dimensions>
<Dimensions>
<Weight>10</Weight>
</Dimensions>
<Color>
<Attribute>Orange</Attribute>
</Color>
<Color>
<Attribute>Blue</Attribute>
</Color>
</Sku>
<Sku>
<Dimensions>
<Height>10</Height>
</Dimensions>
<Dimensions>
<Weight>10</Weight>
</Dimensions>
<Color>
<Attribute>Orange</Attribute>
</Color>
<Color>
<Attribute>Blue</Attribute>
</Color>
</Sku>
</Item>
</Products>
输出预计为象下面这样:
<Products>
<Item>
<Dimensions>
<Height>10</Height>
<Weight>10</Weight>
</Dimensions>
<Color>
<Attribute>Orange</Attribute>
<Attribute>Blue</Attribute>
</Color>
<Sku>
<Dimensions>
<Height>10</Height>
<Weight>10</Weight>
</Dimensions>
<Color>
<Attribute>Orange</Attribute>
<Attribute>Blue</Attribute>
</Color>
</Sku>
<Sku>
<Dimensions>
<Height>10</Height>
<Weight>10</Weight>
</Dimensions>
<Color>
<Attribute>Orange</Attribute>
<Attribute>Blue</Attribute>
</Color>
</Sku>
</Item>
</Products>
任何帮助将不胜感激。 我已经使用了下面的xslt进行转换,但它只是在“Item”下面显示元素。
<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="Item/*[not(self::Sku)]" use="concat(name(), '|', generate-id(..))"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Item">
<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="Item" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答
可以共享相同的逻辑两个集团之间,就像这样:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:key name="elements" match="*" use="concat(name(), '|', generate-id(..))"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template name="GroupChildren">
<xsl:param name="elements" select="*" />
<xsl:for-each select="$elements[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:template>
<xsl:template match="Item">
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:call-template name="GroupChildren">
<xsl:with-param name="elements" select="*[not(self::Sku)]" />
</xsl:call-template>
<xsl:apply-templates select="Sku" />
</xsl:copy>
</xsl:template>
<xsl:template match="Sku">
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:call-template name="GroupChildren" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
当你的样品输入运行,其结果是:
<Products>
<Item>
<Dimensions>
<Height>10</Height>
<Weight>10</Weight>
</Dimensions>
<Color>
<Attribute>Orange</Attribute>
<Attribute>Blue</Attribute>
</Color>
<Sku>
<Dimensions>
<Height>10</Height>
<Weight>10</Weight>
</Dimensions>
<Color>
<Attribute>Orange</Attribute>
<Attribute>Blue</Attribute>
</Color>
</Sku>
<Sku>
<Dimensions>
<Height>10</Height>
<Weight>10</Weight>
</Dimensions>
<Color>
<Attribute>Orange</Attribute>
<Attribute>Blue</Attribute>
</Color>
</Sku>
</Item>
</Products>