Hanu575
Hanu575

Reputation: 15

Remove few nodes in the xml with a match text in the sibling nodes using xslt

Trying to remove few nodes in the xml with a matching text in the sibling nodes using xslt

my xml looks like below

    <?xml version="1.0" encoding="UTF-8"?>
    <root xmlns:map="http://www.w3.org/2005/xpath-functions/map">
    <row>
        <Keep_Name>Africa</Keep_Name>
    </row>
    <row>
        <Keep_Name>USA</Keep_Name>
    </row>
    <row>
        <Keep_Name>Mexico</Keep_Name>
    </row>
    <row>
        <Keep_Name>Canada</Keep_Name>
    </row>
    <row>
        <Keep_Name>Malaysia</Keep_Name>
    </row>
    <row>
        <Remove_Name>Africa</Remove_Name>
    </row>
    <row>
        <Remove_Name>Mexico</Remove_Name>
    </row>
    <row>
        <Remove_Name>Srilanka</Remove_Name>
    </row>
    <row>
        <Keep_Name>Bangladesh</Keep_Name>
    </row>
    </root>`

and the output i need is below

   
    `<?xml version="1.0" encoding="UTF-8"?>
     <root >
     <row>
      <Keep_Name>USA</Keep_Name>
     </row>
     <row>
      <Keep_Name>Canada</Keep_Name>
     </row>
     <row>
      <Keep_Name>Malaysia</Keep_Name>
     </row>
     <row>
      <Keep_Name>Bangladesh</Keep_Name>
     </row>
     </root>

` tried below xslt but not working properly. I want these to remove Remove_Name nodes along with Keep_Name nodes of the same value to be removed altogether from the output

    `<xsl:stylesheet version="2.0" 
       <xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
      <xsl:strip-space elements="*"/>
       <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
     </xsl:template>
    
    
     <xsl:template match="row[.=preceding-sibling::row/.]"/>
     </xsl:stylesheet>`

Tried this above xslt but it is not working as expected.

Please help me to remove these Remove_Name and Keep_Name nodes in the output only if their text is matching.`

Upvotes: 0

Views: 35

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 117102

If I understand the required logic correctly, it could be implemented as:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:key name="row-by-name" match="row" use="Remove_Name" />

<xsl:template match="/root">
    <xsl:copy>
        <xsl:copy-of select="row[Keep_Name][not(key('row-by-name', Keep_Name))]"/>
    </xsl:copy>
</xsl:template>
    
</xsl:stylesheet>

This copies every row with a Keep_Name that doesn't have a matching row with Remove_Name.

Upvotes: 1

Related Questions