I have this input XML which needs to be transformed with an xslt
<root>
<node id="a">
<section id="a_1" method="run">
<item id="0">
<attribute>
<color>Red</color>
</attribute>
</item>
</section>
<section id="a_2">
<item id="0">
<attribute>
<color>Red</color>
</attribute>
</item>
</section>
<section id="a_1" method="run">
<item id="0">
<attribute>
<color>Red</color>
</attribute>
</item>
</section>
</node>
<node id="b">
<section id="b_1" method="create">
<user id="b_1a">
<attribute>
<name>John</name>
</attribute>
</user>
<user id="b_1b">
<attribute>a</attribute>
</user>
</section>
<section id="b_1" method="create">
<user id="b_1c">
<attribute>a</attribute>
</user>
</section>
<section id="b_2">
<user id="b_1a">
<attribute>
<name>John</name>
</attribute>
</user>
</section>
</node>
</root>
Expected output:
<root>
<node id="a">
<section id="a_1">
<item id="0">
<attribute>
<color>Red</color>
</attribute>
</item>
</section>
<section id="a_2">
<item id="0">
<attribute>
<color>Red</color>
</attribute>
</item>
</section>
</node>
<node id="b">
<section id="b_1" method="create">
<user id="b_1a">
<attribute>
<name>John</name>
</attribute>
</user>
<user id="b_1b">
<attribute>a</attribute>
</user>
</section>
<section id="b_2">
<user id="b_1a">
<attribute>
<name>John</name>
</attribute>
</user>
</section>
</node>
</root>
It does not matter which node will be eliminated, as long as it has the same element name, id and method, one of them will be removed.
Any idea what the xsl looks like ?
Note: the element name can be anything doesn’t have to be and it has more than one element name in the whole file; as long as it has the same element name, id and attribute (ex. method=create) one of them will be eliminated.
Thanks very much.
cheers,
John
I. Here is a short and efficient (using keys) XSLT 1.0 transformation:
When this transformation is applied on the provided XML document:
the wanted, correct result is produced:
Explanation:
Using the Muenchian method for grouping with a composite key. Here we ignore (delete) every node that isn’t the first in a group.
II. XSLT 2.0 solution — even shorter and not less efficient:
Explanation:
Proper use of
xsl:for-each-groupwith agroup-byattribute.