2015-05-21 36 views
2

我想用groovy替換xml中的節點值。 我像一個HashMap XPath中的值:Groovy用xpath替換xml中的節點值

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> 

我怎麼能代替節點值?

回答

0

你可以嘗試使用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) 

另一種可能的解決方案

相反,如果你想使用,不僅完整的路徑節點名稱來改變它的值(更強大的)你可以使用.表示法來定義您XPath而不是/表示法並避免根節點名稱(在您的案例中爲Envelope),因爲在解析的xml對象中它已經存在。在代碼

def param = [:]  
// since envelope is the root node it's not necessary 
param["Body.GetWeather.CityName"] = "Berlin" 
param["Body.GetWeather.CountryName"] = "Germany" 

總之:那麼改變你的XPath,你可以有類似

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}" 
    } 

這個片段它是從這個answercomment這是一個解決方法.路徑基於使用變量(一個很好的解決方法IMO :)

希望這有助於,

+0

嗨,這有助於這個例子,但我需要更通用的東西。例如當xml看起來像我應該如何處理這個問題?這就是我想用xpath – Peter

+0

@Peter您可以在答案中使用第二種方法,第二種方法是將「路徑」添加到您的地圖中的元素。 – albciff

+0

嗨,我必須嘗試你的另一種解決方案,只是嘗試第一個 – Peter