ABC
ABC

Reputation: 33

Check for empty XML element using XSLT

I have the following XML

<ns0:Root xmlns:ns0="http://Map_Sample.Input_Schema">
<Number1>
</Number1>
<Number2>11</Number2>
<Number3>12</Number3>
</ns0:Root>

In this case I am getting ENTER or \r\n for Number1. I want to write some XSLT to check if a node contains ENTER or \r\n and then replace it <Number1 />.

Can anyone help me to write the XSLT for this?

Upvotes: 3

Views: 12864

Answers (2)

Maestro13
Maestro13

Reputation: 3696

Try the following:

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

    <xsl:output method="xml" indent="yes"/>

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

    <xsl:template match="*[normalize-space(string(.)) = '']"/>
</xsl:stylesheet>

Explanation: skip output for elements where the (full descendants') text content is pure whitespace.

Upvotes: 0

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243549

There are different possible definitions of what an "empty element" could mean.

Let's define an empty element as one that doesn't have any element nodes children and whose string value is the empty string, or consists only of white space characters (' ', CR, NL).

Then to check if a given element is empty, use:

not(*) and not(normalize-space())

This assumes that the element is the context node when the XPath expression is evaluated.

In this case I am getting "ENTER" or "\r\n" for Number1. I want to write XSLT to check if node contain "ENTER" or "\r\n" then replace it .

You haven't specified with what this text node should be replaced, so in this solution I am assuming the text node should be replaced with the empty string (deleted):

<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(*) and not(normalize-space())]">
  <xsl:element name="{name()}" namespace="{namespace-uri()}"/>
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied on the provided XML document:

<ns0:Root xmlns:ns0="http://Map_Sample.Input_Schema">
    <Number1>
    </Number1>
    <Number2>11</Number2>
    <Number3>12</Number3>
</ns0:Root>

the wanted result is produced:

<ns0:Root xmlns:ns0="http://Map_Sample.Input_Schema">
   <Number1/>
   <Number2>11</Number2>
   <Number3>12</Number3>
</ns0:Root>

Upvotes: 11

Related Questions