1

I am having issue to find out duplicate value of element and remove the node.

XML:

<library>
<books>
<name>Learn XSLT</name>
<id>1</id>
</books>
<books>
<name>Learn Java</name>
<id>3</id>
</books>
<books>
<name>Learn XSLT</name>
<id>2</id>
</books>
</library>

I want to store the duplicate entry that is <name>Learn XSLT</name> and <id>2</id> in variable and remove that books node from XML. I am stuck at how to find those duplicates.

expected output variable containing

<books>
    <name>Learn XSLT</name>
    <id>2</id>
    </books>

output XML

<library>
    <books>
    <name>Learn XSLT</name>
    <id>1</id>
    </books>
    <books>
    <name>Learn Java</name>
    <id>3</id>
    </books>
    </library>
Mads Hansen
  • 63,927
  • 12
  • 112
  • 147
Ironman
  • 556
  • 3
  • 7
  • 21

1 Answers1

0

If you have an xsl:param containing the XML structure to find (or selected it from somewhere, such as an external doc), you could remove the elements in which all of it's child elements match the xsl:param element's child elements, using deep-equal() to perform the comparison.

Using an identity transform with a specialized template to match the element to remove:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="2.0">

  <xsl:output indent="yes"/>

  <xsl:param name="filter">
    <books>
        <name>Learn XSLT</name>
        <id>2</id>
    </books>
  </xsl:param>

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <!--if all of the matched element's children are deep equal to the $filter element's children, 
      then remove it -->
  <xsl:template match="*[deep-equal(*, $filter/*/*)]"/>

</xsl:stylesheet>
Mads Hansen
  • 63,927
  • 12
  • 112
  • 147