当使用XMLSlurper迭代文件时,如何修改XML节点值

时间:2017-05-30 10:37:38

标签: xml groovy

我目前正在迭代这样的XML文件:

def root = new XmlSlurper().parseText(xml)

root.service.each { service ->
  service.receiver.endpoint.each { endpoint ->
    println "\t\tEndpoint: ${endpoint.text()}"
    }
}

我想首先读取endpoint.text(),然后修改节点的值,因此该文件包含一个新值。 我正在阅读节点属性。但是之后我该怎么写呢?

我查看了这个question,并了解如何写入现有文件。但我要问的是,当我已经遍历文件阅读其中的一些内容时,是否可以在更优雅的事情中完成?我希望有一种更有效的方式适合我在文件中迭代的方式。

所以我希望有办法做这样的事情:

def root = new XmlSlurper().parseText(xml)

root.service.each { service ->
  service.receiver.endpoint.each { endpoint ->
    println "\t\tEndpoint: ${endpoint.text()}"
    // ****WRITE TO NODE****
    }
}

希望它有意义。

此外,这里有一些示例XML:

<project name='Common'>
  <service name='name' pattern='something' isReliable='maybe'>
    <receiver name='name' isUsingTwoWaySsl='maybe' isWsRmDisabled='maybe' 
       targetedByTransformation='maybe'>
      <endpoint name='local_tst01'>URL</endpoint>
      <endpoint name='local_tst02'>URL</endpoint>
      <endpoint name='local_tst03'>URL</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>

2 个答案:

答案 0 :(得分:2)

不知道为什么replaceBody方法受到保护但有效:

def root = new XmlSlurper().parseText(
'''<root>
    <service>
        <receiver>
            <endpoint>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 )

答案 1 :(得分:1)

这是更新端点的小变体。

这是灵活的,因此您可以根据下面name attribute地图中定义的endpointBinding选择新网址所需的端点。当然,您可以根据需要更改值。

//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']

pXml = new XmlSlurper().parseText(xml)

//Update the values in xml as per the binding defined above
endpointBinding.collect { k, v -> pXml.'**'.find{it.name() == 'endpoint' && it.@name == k }.replaceBody(v) }    

println groovy.xml.XmlUtil.serialize( pXml )

您可以在线快速尝试 Demo