我需要将此节点合并在一起,但必须与具有属性method="a"
的父级合并
输入:
<myroot>
<elem name="a" creationDate="">
<list id="xxx" ver="uu">
<nodeA id="a">
<fruit id="small">
<orange id="x" method="create">
<color>Orange</color>
</orange>
</fruit>
<fruit id="small" method="a">
<kiwi id="y" method="create">
<color>Red</color>
<type>sour</type>
</kiwi>
</fruit>
<fruit id="large" method="a">
<melon id="y" method="create">
<attributes>
<color>Green</color>
<type>sweet</type>
</attributes>
</melon>
</fruit>
</nodeA>
</list>
</elem>
</myroot>
我的XSL文件:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* , node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="list">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:for-each-group select="/*/*/*/*" group-by="@id">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:for-each-group select="current-group()/*" group-by="concat(local-name(), '|', @id)">
<xsl:copy>
<xsl:apply-templates select="@*, *, (current-group() except .)/*"/>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我的输出:
<myroot>
<elem name="a" creationDate="">
<list id="xxx" ver="uu">
<nodeA id="a">
<fruit id="small">
<orange id="x" method="create">
<color>Orange</color>
</orange>
<kiwi id="y" method="create">
<color>Red</color>
<type>sour</type>
</kiwi>
</fruit>
<fruit id="large" method="a">
<melon id="y" method="create">
<attributes>
<color>Green</color>
<type>sweet</type>
</attributes>
</melon>
</fruit>
</nodeA>
</list>
</elem>
</myroot>
预期输出:
<myroot>
<elem name="a" creationDate="">
<list id="xxx" ver="uu">
<nodeA id="a">
<fruit id="small" method="a"> <!-- this is the correct merge where the merged is in parent that has a method -->
<kiwi id="y" method="create">
<color>Red</color>
<type>sour</type>
</kiwi>
<orange id="x" method="create">
<color>Orange</color>
</orange>
</fruit>
<fruit id="large" method="a">
<melon id="y" method="create">
<attributes>
<color>Green</color>
<type>sweet</type>
</attributes>
</melon>
</fruit>
</nodeA>
</list>
</elem>
</myroot>
正如我们所看到的,我的转换只将它们组合在一起而不考虑方法。如何更改它以便它将合并到示例中为method="a"
的{{1}}的父<fruit id="small" method="a">
谢谢。 约翰
答案 0 :(得分:1)
在<xsl:for-each-group>
元素中,上下文项只是该组的第一个元素,因此select="@*"
将仅复制第一个元素的属性。要在任何元素中获取所有不同命名属性的副本,您需要访问current-group()/@*
。
也不需要select="*, (current-group() except .)/*"
,因为它等同于select="current-group()/*"
。
完整的样式表看起来像这样
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@*, node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="list">
<xsl:copy>
<xsl:copy-of select="@*" />
<xsl:apply-templates select="*" />
</xsl:copy>
</xsl:template>
<xsl:template match="list/*">
<xsl:copy>
<xsl:copy-of select="@*" />
<xsl:for-each-group select="*" group-by="concat(local-name(), '|', @id)">
<xsl:copy>
<xsl:copy-of select="current-group()/@*" />
<xsl:copy-of select="current-group()/*" />
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>