2017-05-31 90 views
1

在擴展到this的問題,我現在試圖替換XML節點的屬性。如何在使用XMLSlurper遍歷文件時修改XML節點屬性?

我已經使用下面的代碼寫入了XML的主體。

def root = new XmlSlurper().parseText(
'''<root> 
    <service> 
     <receiver> 
     <endpoint type="type1">123</endpoint> 
     <endpoint>456</endpoint> 
     </receiver> 
    </service> 
</root>''') 

root.service.each { service -> 
service.receiver.endpoint.each { endpoint -> 
    endpoint.replaceBody("**"+endpoint.text()) 
    } 
} 

println groovy.xml.XmlUtil.serialize(root) 

我想檢查type屬性是否存在。如果是這樣,我想改變它的值來說「type2」。

是否有與replaceBody()替代屬性的等價方法?

還是我必須以不同方式實施?

+0

喬納斯,請看看我的解決方案幫助和靈活,爲不同的端點名稱不同類型的值。 – Rao

回答

2

這裏只是一個班輪更新所需的屬性:

root.'**'.findAll{it.name() == 'endpoint' && it.attributes().get('type') }*[email protected]= 'type_value' 

下面是基於參照其他信息以前的問題數據。 讓我們假設有更多的端點local_tst01,local_tst02,並且您希望具有不同的類型值(爲了靈活性,不希望每個端點具有相同的類型值)。在這種情況下,你可以使用下面的腳本。

在這裏你也可以使用地圖端點名稱的和低於所需的類型值:

typeBinding = ['local_tst01': 'type01', 'local_tst02': 'type02', 'local_tst03': 'type03'] 

然而,讓我們假設沒有類型的端點,併爲每OP,類型不應該有在輸出爲endpoint whose name is local_tst03,說:

<endpoint name='local_tst01' type='123'>URL1</endpoint> 
<endpoint name='local_tst02' type='xyz'>URL2</endpoint> 
<endpoint name='local_tst03'>URL3</endpoint> 

下面是完整的腳本:

def xml = """<project name='Common'> 
    <service name='name' pattern='something' isReliable='maybe'> 
    <receiver name='name' isUsingTwoWaySsl='maybe' isWsRmDisabled='maybe' 
     targetedByTransformation='maybe'> 
     <endpoint name='local_tst01' type='123'>URL1</endpoint> 
     <endpoint name='local_tst02' type='xyz'>URL2</endpoint> 
     <endpoint name='local_tst03'>URL3</endpoint> 
     <environment name='dev' default='local_dev' /> 
     <environment name='tst01' default='test' /> 
     <environment name='tst02' default='local_tst02' /> 
    </receiver> 
    <operation name='name'> 
     <sender>sender</sender> 
     <attribute name='operation' type='String'>name</attribute> 
    </operation> 
    </service> 
</project>""" 


//Set your endpoint name attribute value and new endpoint url in a map 
//This would be flexible to have the respective url 
def endpointBinding = ['local_tst01': 'http://example01.com', 'local_tst02': 'http://example02.com', 'local_tst03': 'http://example03.com'] 
def typeBinding = ['local_tst01': 'type01', 'local_tst02': 'type02', 'local_tst03': 'type03'] 
pXml = new XmlSlurper().parseText(xml) 
//update endpoint value 
endpointBinding.collect { k, v -> pXml.'**'.find{it.name() == 'endpoint' && [email protected] == k }.replaceBody(v)} 

//update type 
typeBinding.collect { k, v -> pXml.'**'.find{it.name() == 'endpoint' && it.attributes().get('type') && [email protected] == k }[email protected] = v} 

println groovy.xml.XmlUtil.serialize(pXml) 

您可以快速地嘗試這個網上Demo

1
def root = new XmlSlurper().parseText(
'''<root> 
    <service> 
     <receiver> 
     <endpoint type="type1">123</endpoint> 
     <endpoint>456</endpoint> 
     </receiver> 
    </service> 
</root>''') 

root.service.each { service -> 
    service.receiver.endpoint.each { endpoint -> 
     endpoint.replaceBody("**"+endpoint.text()) 
     if([email protected]=='type1')[email protected]='type-01' 
     else [email protected]='type-99' 
    } 
} 

println groovy.xml.XmlUtil.serialize(root) 

,或者你可以得到所有屬性的地圖與endpoint.attributes()