xml - 使用 XMLSlurper 迭代文件时如何修改 XML 节点属性?

标签 xml groovy

作为 this 问题的扩展,我现在正在尝试替换 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() 等效的方法?

或者我必须以不同的方式实现它吗?

最佳答案

这里只是更新所需属性的一行代码:

root.'**'.findAll{it.name() == 'endpoint' && it.attributes().get('type') }*.@type= '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' && it.@name == k }.replaceBody(v)}

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

println groovy.xml.XmlUtil.serialize( pXml )

​您可以在线快速尝试 Demo

关于xml - 使用 XMLSlurper 迭代文件时如何修改 XML 节点属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44285176/

相关文章:

xml - XProc:使用中间文件进行多重 XSLT 转换

jenkins - 使用 init.groovy.d 脚本中的管道初始化 Jenkins 2.0

c# - 将 Java Triple DES 结果与 C# 1 相匹配

c# - 在 C# 中使用 XML 文字?

android - Android中的自定义EditText : How do you reference in XML Layout?

scala中的xml属性解析

SQL在Groovy中执行不等到它完成才返回

java - 是否还有其他方法可以除了 option.ifpresent() 之外检查值是否已填充

eclipse - eclipse 无法设置断点

data-binding - Grails 自动将字符串强制转换为我的域类之一