Groovy 用 xpath 替换 xml 中的节点值
Groovy replace node values in xml with xpath
我想在 groovy 中替换 xml 中的节点值。
我在散列图中的 xpath 中有值,例如:
def param = [:]
param["/Envelope/Body/GetWeather/CityName"] = "Berlin"
param["/Envelope/Body/GetWeather/CountryName"] = "Germany"
XML 文件:
<?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>
如何替换节点值?
您可以尝试使用 XmlSlurper
代替,这可能是一种简单的方法。您可以使用节点名称作为键来定义您的地图,并将文本作为值迭代它,从而更改 Xml 中的节点。您可以使用类似于以下代码的内容:
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)
另一种可能的解决方案
相反,如果您想使用完整路径而不仅仅是节点名称来更改其值(更稳健),您可以使用 .
符号而不是 [=17] 来定义 XPath
=] 符号并避免使用根节点名称(在您的情况下为 Envelope
),因为在解析的 xml 对象中它已经存在。所以改变你的 XPath 你可以有这样的东西:
def param = [:]
// since envelope is the root node it's not necessary
param["Body.GetWeather.CityName"] = "Berlin"
param["Body.GetWeather.CountryName"] = "Germany"
全部在代码中:
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)
请注意,在第二个解决方案中我使用了这个片段:
def node = xml
key.split("\.").each {
node = node."${it}"
}
此片段来自此 answer and comment,它是解决 .
基于变量的路径的解决方法(IMO :)
的一个很好的解决方法)
希望对您有所帮助,
我想在 groovy 中替换 xml 中的节点值。 我在散列图中的 xpath 中有值,例如:
def param = [:]
param["/Envelope/Body/GetWeather/CityName"] = "Berlin"
param["/Envelope/Body/GetWeather/CountryName"] = "Germany"
XML 文件:
<?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>
如何替换节点值?
您可以尝试使用 XmlSlurper
代替,这可能是一种简单的方法。您可以使用节点名称作为键来定义您的地图,并将文本作为值迭代它,从而更改 Xml 中的节点。您可以使用类似于以下代码的内容:
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)
另一种可能的解决方案
相反,如果您想使用完整路径而不仅仅是节点名称来更改其值(更稳健),您可以使用 .
符号而不是 [=17] 来定义 XPath
=] 符号并避免使用根节点名称(在您的情况下为 Envelope
),因为在解析的 xml 对象中它已经存在。所以改变你的 XPath 你可以有这样的东西:
def param = [:]
// since envelope is the root node it's not necessary
param["Body.GetWeather.CityName"] = "Berlin"
param["Body.GetWeather.CountryName"] = "Germany"
全部在代码中:
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)
请注意,在第二个解决方案中我使用了这个片段:
def node = xml
key.split("\.").each {
node = node."${it}"
}
此片段来自此 answer and comment,它是解决 .
基于变量的路径的解决方法(IMO :)
的一个很好的解决方法)
希望对您有所帮助,