abbasdgr8
abbasdgr8

Reputation: 555

How to remove empty XML nodes using Java or XSLT

I have the following XML document:

<?xml version="1.0" encoding="utf-8"?>
<greatGrandParent>
    <grandParent>
        <parent>
            <sibling>Fred</sibling>
            <sibling>Max</sibling>
            <sibling>Katie</sibling>
        </parent>
        <parent>
            <sibling>Lindy</sibling>
            <sibling>Richard</sibling>
        </parent>
        <parent>
            <sibling />
        </parent>
    </grandParent>
    <grandParent>
        <parent>
            <sibling>Steve</sibling>
            <sibling>Abbas</sibling>
        </parent>
        <parent>
            <sibling>Kate</sibling>
            <sibling>James</sibling>
            <sibling>Ian</sibling>
        </parent>
    </grandParent>
    <grandParent>
        <parent>
            <sibling />
        </parent>
    </grandParent>
</greatGrandParent>

My requirement is - to remove an XML node if all of its child elements are empty. For instance, in the above shown XML,

Hence, the resulting XML must look like:

<?xml version="1.0" encoding="utf-8"?>
<greatGrandParent>
    <grandParent>
        <parent>
            <sibling>Fred</sibling>
            <sibling>Max</sibling>
            <sibling>Katie</sibling>
        </parent>
        <parent>
            <sibling>Lindy</sibling>
            <sibling>Richard</sibling>
        </parent>
    </grandParent>
    <grandParent>
        <parent>
            <sibling>Steve</sibling>
            <sibling>Abbas</sibling>
        </parent>
        <parent>
            <sibling>Kate</sibling>
            <sibling>James</sibling>
            <sibling>Ian</sibling>
        </parent>
    </grandParent>
</greatGrandParent>

I'd be glad if somebody can suggest me a solution to do this using any Java API or XSLT.

Upvotes: 0

Views: 5238

Answers (1)

Mark Veenstra
Mark Veenstra

Reputation: 4739

You could use the following XSLT for this:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" exclude-result-prefixes="fn xs">
        <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
        <xsl:template match="node()|@*">
                <xsl:if test="normalize-space(string(.)) != ''">
                        <xsl:copy>
                                <xsl:apply-templates select="node()|@*"/>
                        </xsl:copy>
                </xsl:if>
        </xsl:template>
</xsl:stylesheet>

To get an idea of how it works, execute the next XSLT that gives you an extra element on grandParent node, also read this little tutorial: http://www.xmlplease.com/xsltidentity

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

    <xsl:template match="grandParent">
        <xsl:copy>
            <xsl:apply-templates select="@*" />
            <childValues><xsl:value-of select="normalize-space(.)" /></childValues>
            <xsl:apply-templates select="node()" />
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

Upvotes: 3

Related Questions