0

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.

8
  • 1
  • Try match="node()[.='']" instead of match="@xsi:nil[.='true']" Commented Jul 19, 2016 at 12:36
  • 1
    ps. looking at the answers on @Filburt's links there's one crucial difference between how they behave compared to my note above; that is in handling elements containing only empty elements: e.g. <OrderDetails><CommentLine/></OrderDetails>. Decide how you want it to behave in that scenario then compare the answers presented with this test data to see what fits (i.e. mine would preserve the empty OrderDetails element; others wouldn't). That could also be addressed by adding other filters (e.g. targeting only elements called CommentLine). Commented Jul 19, 2016 at 12:44
  • @JohnLBevan I tried the same as you suggested . But it did not worked for me. Commented Jul 19, 2016 at 12:46
  • It is not removing <CommentLine/> Commented Jul 19, 2016 at 12:47

1 Answer 1

1

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:

Sign up to request clarification or add additional context in comments.

1 Comment

when i am adding this template getting following error : paste.ofcode.org/AibFyqZYNCv4ZHhSmsdDEd i am also getting duplicate data for <commentLine> tag . is that possible to remove duplicate tag using xslt 2.0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.