I need to merge this node together, but it has to be merged with the parent that has an attribute method="a"
Input:
<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>
my XSL file:
<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>
my output:
<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>
Expected Output:
<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>
As we can see my transformation only combine it together and does not consider the method. How to change it so it will be merged to parent that has method="a" in the example it is <fruit id="small" method="a">
Thank you.
John
Within an
<xsl:for-each-group>element the context item is just the first element of the group, soselect="@*"will copy just the attributes of the first element. To get a copy of all differently-named attributes in any element you need to accesscurrent-group()/@*.There is also no need to
select="*, (current-group() except .)/*"as it is equivalent toselect="current-group()/*".The complete stylesheet looks like this