Delete the same node with the same attribute under the same parent in XML using xslt
I need to convert this XML input:
<root>
<node id="a">
<section id="a_1" method="run">
<item id="0" method="a">
<attribute>
<color>Red</color>
<status>1</status>
<condition>good</condition>
</attribute>
</item>
<item id="0" method="a">
<attribute>
<color>Red</color>
<status>1</status>
<condition>good</condition>
</attribute>
</item>
</section>
<section id="a_2" method="run">
<item id="0" method="a">
<attribute>
<color>Red</color>
<status>1</status>
<condition>good</condition>
</attribute>
</item>
</section>
</node>
<node id="b">
<section id="b_1" method="create">
<user id="b_1a" method="x">
<attribute>
<origin>us</origin>
</attribute>
</user>
<user id="b_1a" method="x">
<attribute>
<origin>us</origin>
</attribute>
</user>
<user id="b_1b">
<attribute>a</attribute>
</user>
</section>
<section id="b_2">
<user id="b_1a" method="x">
<attribute>
<name>John</name>
<origin>us</origin>
</attribute>
</user>
</section>
</node>
</root>
Here is the expected result:
<root>
<node id="a">
<section id="a_1" method="run">
<item id="0" method="a">
<attribute>
<color>Red</color>
<status>1</status>
<condition>good</condition>
</attribute>
</item>
</section>
<section id="a_2" method="run">
<item id="0" method="a">
<attribute>
<color>Red</color>
<status>1</status>
<condition>good</condition>
</attribute>
</item>
</section>
</node>
<node id="b">
<section id="b_1" method="create">
<user id="b_1a" method="x">
<attribute>
<origin>us</origin>
</attribute>
</user>
<user id="b_1b">
<attribute>a</attribute>
</user>
</section>
<section id="b_2">
<user id="b_1a" method="x">
<attribute>
<name>John</name>
<origin>us</origin>
</attribute>
</user>
</section>
</node>
</root>
Note: a duplicate means that all children / children have the same value, a node can have 1 or more children if it is the same parent (id and method are the same), and we can assume that it is always in the same section ( id and method are the same).
can this be done? please enlighten me
Many thanks.
amuses John
I. This is an XSLT 1.0 conversion :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kElemWithAttribs" match="*[@id and @method]"
use="concat(generate-id(..), '+', name(), '+', @id, '+', @method)"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"*[@id and @method
and
not(generate-id()
=
generate-id(key('kElemWithAttribs',
concat(generate-id(..),
'+',name(), '+', @id, '+', @method)
)[1]
)
)
]"/>
</xsl:stylesheet>
when applied to the provided XML source document:
<root>
<node id="a">
<section id="a_1" method="run">
<item id="0" method="a">
<attribute>
<color>Red</color>
<status>1</status>
<condition>good</condition>
</attribute>
</item>
<item id="0" method="a">
<attribute>
<color>Red</color>
<status>1</status>
<condition>good</condition>
</attribute>
</item>
</section>
<section id="a_2" method="run">
<item id="0" method="a">
<attribute>
<color>Red</color>
<status>1</status>
<condition>good</condition>
</attribute>
</item>
</section>
<section id="a_2" method="run">
<item id="0" method="a">
<attribute>
<color>Red</color>
<status>1</status>
<condition>good</condition>
</attribute>
</item>
</section>
</node>
<node id="b">
<section id="b_1" method="create">
<user id="b_1a" method="x">
<attribute>
<origin>us</origin>
</attribute>
</user>
<user id="b_1a" method="x">
<attribute>
<origin>us</origin>
</attribute>
</user>
<user id="b_1b">
<attribute>a</attribute>
</user>
</section>
<section id="b_2">
<user id="b_1a" method="x">
<attribute>
<name>John</name>
<origin>us</origin>
</attribute>
</user>
</section>
</node>
</root>
creates the desired, correct result:
<root>
<node id="a">
<section id="a_1" method="run">
<item id="0" method="a">
<attribute>
<color>Red</color>
<status>1</status>
<condition>good</condition>
</attribute>
</item>
</section>
<section id="a_2" method="run">
<item id="0" method="a">
<attribute>
<color>Red</color>
<status>1</status>
<condition>good</condition>
</attribute>
</item>
</section>
</node>
<node id="b">
<section id="b_1" method="create">
<user id="b_1a" method="x">
<attribute>
<origin>us</origin>
</attribute>
</user>
<user id="b_1b">
<attribute>a</attribute>
</user>
</section>
<section id="b_2">
<user id="b_1a" method="x">
<attribute>
<name>John</name>
<origin>us</origin>
</attribute>
</user>
</section>
</node>
</root>
. Muenchian , :
node "as-is".
xsl:key. , , ,id,method( ) , ,idmethod., . ,
id,method( ) ). , ( , "" ).- 3. , , . , - , .
II. XSLT 2.0:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[@id]">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:for-each-group select="*" group-by=
"concat(generate-id(..), '+', name(), '+', @id, '+', @method)">
<xsl:apply-templates select="."/>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
. xsl:for-each-group group-by.