Reputation: 103
I have this XML code:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<A>
<B>
<C index="0">
<element index="0">one</element>
<element index="1">two</element>
<keyElement index="1">key</keyElement >
</C>
<C index="0">
<element index="0">one</element>
<element index="1">two</element>
<keyElement index="1">key</keyElement >
</C>
</B>
</A>
</root>
and I want to remove duplicates based on index value. I am already using a key for the keyElement which I am using in the iteration.
<xsl:key name="group-by-keyElement" match="C" use="keyElement" />
<xsl:for-each select="key('group-by-keyElement', keyElement )">
In the same iteration I need to remove the duplicates so that the output shows only once the values in C.
The result wanted is this:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<A>
<B>
<C index="0">
<element index="0">one</element>
<element index="1">two</element>
<keyElement index="1">key</keyElement >
</C>
</B>
</A>
</root>
Upvotes: 0
Views: 1492
Reputation: 30971
You wrote: I want to remove duplicates based on index value. I assume, you mean the value of index attribute in C tag.
Below you have a solution, working in both XSLT 1.0 and XSLT 2.0.
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:key name="indexKey" match="//C[@index]" use="@index" />
<xsl:template match="C">
<xsl:if test="generate-id()=generate-id(key('indexKey', @index)[1])">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:if>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
</xsl:template>
</xsl:transform>
The key point is template matching C tag.
The first thing to do is to check whether the id generted for the current node
(generate-id()
) is equal to the id generated for the first element
returned by key
function from key named indexKey and value of
the current index attribute.
If this is the case, then:
Upvotes: 1