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.

Filburt
  • 17,626
  • 12
  • 64
  • 115
NEO
  • 389
  • 8
  • 31
  • 1
    Related: [How to tell using xpath if an element is present and non empty](http://stackoverflow.com/q/15909348/205233) and [XSL / XPath expression to check if a node contains at least one non-empty child](http://stackoverflow.com/q/13703478/205233). – Filburt Jul 19 '16 at 12:34
  • Try `match="node()[.='']"` instead of `match="@xsi:nil[.='true']"` – JohnLBevan Jul 19 '16 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. ``. 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`). – JohnLBevan Jul 19 '16 at 12:44
  • @JohnLBevan I tried the same as you suggested . But it did not worked for me. – NEO Jul 19 '16 at 12:46
  • It is not removing – NEO Jul 19 '16 at 12:47
  • Interesting; what XSLT engine are you using? http://xsltransform.net/gWvjQgq – JohnLBevan Jul 19 '16 at 12:52
  • ps. regarding my comment about mine leaving empty parent elements; that's not true; I think I made a mistake in my testing; not sure what... Will provide an answer which includes that option... – JohnLBevan Jul 19 '16 at 12:57
  • we are using SAXON . – NEO Jul 19 '16 at 13:05

1 Answers1

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:

Community
  • 1
  • 1
JohnLBevan
  • 22,735
  • 13
  • 96
  • 178
  • when i am adding this template getting following error : http://paste.ofcode.org/AibFyqZYNCv4ZHhSmsdDEd i am also getting duplicate data for tag . is that possible to remove duplicate tag using xslt 2.0 – NEO Jul 22 '16 at 13:30