Somebody
Somebody

Reputation: 2779

Conditionally remove empty elements from XML using XSLT 1.0

I need to remove below empty elements from the sample XML following below rules:

  1. perm elements cannot be removed, even if they are empty
  2. delete empty elements only if attr has default empty values attr="a='';b=''"
  3. empty elements altogether (without any attributes) should be also deleted

Sample XML

<?xml version="1.0" encoding="UTF-8"?>
<item>
    <perm desc="item_1" attr="a='';b=''">
        <content></content>
        <desc>Item 1</desc>
        <details>
            <firstname desc="Name" attr="a='';b=''">John</firstname>
            <lastname desc="Last" attr="a='';b=''"></lastname>
            <phone desc="phone" attr="a='';b='561-663-1254'"></phone>
        </details>
    </perm>
    <perm desc="item_2" attr="a='';b=''"></perm>    
</item>

Expected output XML

<?xml version="1.0" encoding="UTF-8"?>
<item>
    <perm desc="item_1" attr="a='';b=''">        
        <desc>Item 1</desc>
        <details>
            <firstname desc="Name" attr="a='';b=''">John</firstname>            
            <phone desc="phone" attr="a='';b='561-663-1254'"></phone>
        </details>
    </perm>
    <perm desc="item_2" attr="a='';b=''"></perm>    
</item>

I'm using below XSLT 1.0 but I'm not able to get the expected result, what changes do I need to make for it to work?

<?xml version="1.0" encoding="UTF-8" ?>
<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:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="@*[.='']"/>
<xsl:template match="*[not(node())]"/>

</xsl:stylesheet>

Upvotes: 0

Views: 75

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167506

Not all conditions are clear but the following should get you further than your intent:

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

<xsl:template match="*[not(self::perm)][not(@*|node())] | *[not(self::perm)][not(node()) and @attr = &quot;a='';b=''&quot;]"/>

</xsl:stylesheet>

Upvotes: 1

Related Questions