NEO
NEO

Reputation: 399

Using XSLT, how to remove the empty element, which does not have an attribute or data, in an XML document?

We want to remove empty Tag that is CommentLine from XML

<CommentLine/>

INPUT XML :

<?xml version="1.0" encoding="WINDOWS-1252"?>
<SalesOrders xsd:noNamespaceSchemaLocation="SDOC.XSD" xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance">   
  <Orders>   
    <OrderHeader>  
      <CustomerPoNumber>AB-54354</CustomerPoNumber>  
    </OrderHeader>   
    <OrderDetails>   
      <CommentLine>
        <Comment>Ensure saddle is color coded</Comment>  
        <OrderLineID>OR-1810127</OrderLineID>  
      </CommentLine>  
      <CommentLine>
        <Comment>EDI-001</Comment>  
        <OrderLineID>OR-1810128</OrderLineID>  
      </CommentLine>  
      <StockLine>  
        <CustomerPoLine>9999</CustomerPoLine>  
        <StockCode>ABSH-SMH-12OZ-01</StockCode> 
        <StockDescription>SMH ABS BALANCE SHAMPOO 12OZ</StockDescription>  
        <OrderQty>1.0</OrderQty>
      </StockLine>  
      <CommentLine>
        <Comment>This is for test purpose</Comment>  
        <OrderLineID>OR-1810124</OrderLineID>  
      </CommentLine>   
      <CommentLine>  
        <Comment>EDI-SAVE</Comment> 
        <OrderLineID>OR-1810125</OrderLineID>  
      </CommentLine>

      <CommentLine/>

    </OrderDetails>  
  </Orders>  
</SalesOrders>

Tried XML on it:

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

<xsl:template match="@xsi:nil[.='true']" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>

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

Expected output

<?xml version="1.0" encoding="WINDOWS-1252"?>  -<SalesOrders xsd:noNamespaceSchemaLocation="SDOC.XSD" xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance">   
            -<Orders>   
            -<OrderHeader>  
            <CustomerPoNumber>AB-54354</CustomerPoNumber>  
            </OrderHeader>   
            -<OrderDetails>   
            -<CommentLine>  <Comment>Ensure saddle is color coded</Comment>  
            <OrderLineID>OR-1810127</OrderLineID>  

            </CommentLine>  
            -<CommentLine>  <Comment>EDI-001</Comment>  
            <OrderLineID>OR-1810128</OrderLineID>  
            </CommentLine>  
            -<StockLine>  
            <CustomerPoLine>9999</CustomerPoLine>  
            <StockCode>ABSH-SMH-12OZ-01</StockCode> 
             <StockDescription>SMH ABS BALANCE SHAMPOO 12OZ</StockDescription>  
            <OrderQty>1.0</OrderQty> </StockLine>  
             -<CommentLine>  <Comment>This is for test purpose</Comment>  
            <OrderLineID>OR-1810124</OrderLineID>  
            </CommentLine>   
            -<CommentLine>  
            <Comment>EDI-SAVE</Comment> 
             <OrderLineID>OR-1810125</OrderLineID>  
            </CommentLine>  

            </OrderDetails>  
            </Orders>  
            </SalesOrders>

we have to remove element in complete Input XML.

Any help would be much appreciated ! Thanks for valuable time.

Upvotes: 0

Views: 890

Answers (1)

JohnLBevan
JohnLBevan

Reputation: 24470

This solution will remove any empty elements without removing their parent elements (i.e. if you had <OrderDetails><CommentLine/></OrderDetails> you'd get and empty OrderDetails element in your result set.

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

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

</xsl:stylesheet>

i.e. I'm telling the system to only return nodes which have child nodes (be they element or text). <xsl:template match="@*|node()[./node()]">

Demo: http://xsltransform.net/jyRYYjs

Per @Filburt's comments, if you wanted to also remove elements which become empty once their empty child elements are removed, follow the advise on these links:

Upvotes: 1

Related Questions