Search code examples
xmlgroovyxml-parsing

Remove empty tags from XML in Groovy


Sorry for bothering with a primitive question. i have a the following xml output with the multi map format.

The empty tags and the multi map tags need to be removed from the xml.

<?xml version='1.0' encoding='UTF-8'?>
<multimap:Messages xmlns:multimap="http://sap.com/xi/XI/SplitAndMerge">
    <multimap:Message1>
        <root>
            <budgets/>
        </root>
        <root>
            <budgets/>
        </root>
        <root>
            <budgets>
                <id>1234</id>
                <field2>4496</field2>
                <field3>test</field3>
            </budgets>
        </root>
        <root>
            <budgets/>
        </root>
        <root>
            <budgets>
        </root>
    </multimap:Message1>
</multimap:Messages>

The expected output as follows

<base1> 
    <root>
        <budgets>
            <id>1234</id>
            <field2>4496</field2>
            <field3>test</field3>
        </budgets>
    </root>
</base1>

tried the following code,

def body = message.getBody(java.lang.String) as String;
body = body.replaceAll("<multimap:Messages xmlns:multimap=", "");
body = body.replaceAll("\"http://sap.com/xi/XI/SplitAndMerge\">", "");
body = body.replaceAll("</multimap:Messages>", "");
body = body.replaceAll("multimap:Message", "base")
body = body.replaceAll("\\<\\?xml(.+?)\\?\\>", "").trim();

def list = new XmlParser().parseText(body)
def list1 = list.'**'.findAll{it.children().size() == 0 }
list1.each{ 
    list.remove(it)
}

Tried with the following code as well:

list.'**'.removeAll{ it.children().size() == 0 }

Not sure what i am missing here. Your help in solving this is highly appreciated.


Solution

  • Using some simple XML processing:

    import groovy.xml.*
    
    def xml = new XmlSlurper().parseText '''\
    <?xml version='1.0' encoding='UTF-8'?>
    <multimap:Messages xmlns:multimap="http://sap.com/xi/XI/SplitAndMerge">
        <multimap:Message1>
            <root>
                <budgets/>
            </root>
            <root>
                <budgets/>
            </root>
            <root>
                <budgets>
                    <id>1234</id>
                    <field2>4496</field2>
                    <field3>test</field3>
                </budgets>
            </root>
            <root>
                <budgets/>
            </root>
            <root>
                <budgets/>
            </root>
        </multimap:Message1>
    </multimap:Messages>'''
    
    List notEmptyBudgets = xml.'**'.findAll{ 'budgets' == it.name() && it.children().size() }
    
    def writer = new StringWriter()
    
    def out = new StreamingMarkupBuilder().bind{
      base1{
        root{
          notEmptyBudgets.each{ b ->
            budgets{
              b.children().each{ "${it.name()}" it.text() }
            }
          }
        }
      }
    }
    
    XmlUtil.serialize out
    

    returns

    <?xml version="1.0" encoding="UTF-8"?><base1>
      <root>
        <budgets>
          <id>1234</id>
          <field2>4496</field2>
          <field3>test</field3>
        </budgets>
      </root>
    </base1>