I want to replace the node values in a xml in groovy. I have the values in xpath in a hashmap like:
def param = [:]
param["/Envelope/Body/GetWeather/CityName"] = "Berlin"
param["/Envelope/Body/GetWeather/CountryName"] = "Germany"
XML File:
<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<web:GetWeather xmlns:web="http://www.webserviceX.NET">
<web:CityName>Test</web:CityName>
<web:CountryName>Test</web:CountryName>
</web:GetWeather>
</soapenv:Body>
</soapenv:Envelope>
How can I replace the node values?
You can try using XmlSlurper
instead probably it's an easy way. You can define your map using the node name as a key and the text as a value iterate over it changing the node in the Xml. You can use something similar the code below:
import groovy.util.XmlSlurper
import groovy.xml.XmlUtil
def xmlString = '''<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<web:GetWeather xmlns:web="http://www.webserviceX.NET">
<web:CityName>Test</web:CityName>
<web:CountryName>Test</web:CountryName>
</web:GetWeather>
</soapenv:Body>
</soapenv:Envelope>'''
def param = [:]
param["CityName"] = "Berlin"
param["CountryName"] = "Germany"
// parse the xml
def xml = new XmlSlurper().parseText(xmlString)
// for each key,value in the map
param.each { key,value ->
// change the node value if the its name matches
xml.'**'.findAll { if(it.name() == key) it.replaceBody value }
}
println XmlUtil.serialize(xml)
Another possible solution
Instead if you want to use the complete path not only the node name to change its value (to be more robust) you can define you XPath
using .
notation instead of /
notation and avoid root node name (in your case Envelope
) because in the parsed xml object it's already there. So changing your XPath you can have something like:
def param = [:]
// since envelope is the root node it's not necessary
param["Body.GetWeather.CityName"] = "Berlin"
param["Body.GetWeather.CountryName"] = "Germany"
All together in the code:
import groovy.util.XmlSlurper
import groovy.xml.XmlUtil
def xmlString = '''<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<web:GetWeather xmlns:web="http://www.webserviceX.NET">
<web:CityName>Test</web:CityName>
<web:CountryName>Test</web:CountryName>
</web:GetWeather>
</soapenv:Body>
</soapenv:Envelope>'''
def param = [:]
// since envelope is the root node it's not necessary
param["Body.GetWeather.CityName"] = "Berlin"
param["Body.GetWeather.CountryName"] = "Germany"
def xml = new XmlSlurper().parseText(xmlString)
param.each { key,value ->
def node = xml
key.split("\\.").each {
node = node."${it}"
}
node.replaceBody value
}
println XmlUtil.serialize(xml)
Note that in the second solution I use this snippet:
def node = xml
key.split("\\.").each {
node = node."${it}"
}
This snippet it's from this answer and comment which is a workaround to solve .
path based using variables (a good workaround IMO :)
)
Hope this helps,
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With