2017-05-31 88 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()