Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove a specific xml node with namespace using groovy

Trying to remove xml nodes using groovy. Here want to remove requiredByDate element, which is present multiple times and has namcespace with a prefix.

Looked at many examples available on the net, and stackover as well. Some of them are close. If there is no namespace for that xml element, then getting the desired output.


Problem is that the xml element has namespace and not able to achieve the intended out.

Here is the groovy script that I am trying:

import groovy.xml.*
def x='''<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:com="http://www.example/test/commontypes" xmlns:ord="http://www.example/test/orderservice" xmlns:ord1="http://www.example/test/order">
   <soapenv:Header/>
   <soapenv:Body>
         <ord:orderRequest>
            <ord1:orderRef>${#TestCase#ORDERREF}</ord1:orderRef>
            <ord1:header>
               <ord1:description>user test</ord1:description>
               <ord1:customerID></ord1:customerID>
               <ord1:requiredByDate>2010-02-02T12:00:00-07:00</ord1:requiredByDate>               
            </ord1:header>
            <ord1:line>
               <ord1:lineNumber>1</ord1:lineNumber>
               <ord1:actionMode>mode1</ord1:actionMode>
               <ord1:requiredByDate>2010-02-02T12:00:00-07:00</ord1:requiredByDate>
            </ord1:line>
            <ord1:line>
               <ord1:lineNumber>2</ord1:lineNumber>
               <ord1:action>userAction</ord1:action>
               <ord1:requiredByDate>2010-02-02T12:00:00-07:00</ord1:requiredByDate>
            </ord1:line>
         </ord:orderRequest>
   </soapenv:Body>
</soapenv:Envelope>'''
def xml=new XmlParser().parseText(x)
def nodes = xml.'**'.findAll{ it.name() == 'requiredByDate' }
nodes.each{it.parent().remove(it)}
XmlUtil.serialize(xml).toString()

The output comes the same as input i.e., does not remove requiredByDate elements(present 3 times in the xml)

If I hard code with namespace i.e., 'ord1:requiredByDate', then desired output comes. Referring xml.'**'.findAll{ it.name() == 'ord1:requiredByDate' } here.

However, I do not know what prefix comes in the xml during runtime. Hence, cannot use the hardcoded prefix in findAll above.

like image 648
Rao Avatar asked Feb 06 '26 18:02

Rao


1 Answers

A node with a namespace return a QName for his name() method. You can access the "local" name of the node, without the namespace, with the method QName.getLocalPart()

Try this:

def nodes = xml.'**'.findAll{ it.name().localPart == 'requiredByDate' }

See QName

Or the javadoc for Node:

Typically the name is a String and a value is either a String or a List of other Nodes, though the types are extensible to provide a flexible structure, e.g. you could use a QName as the name which includes a namespace URI and a local name.

like image 68
Jérémie B Avatar answered Feb 09 '26 12:02

Jérémie B



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!