更新XML元素值而不修改Groovy中的结构

时间:2018-01-09 11:45:13

标签: xml groovy

我的要求是在Groovy中更新XML元素的值。下面是代码。代码是在名称为Super1时将状态更新为启用。

def xmlfile = new File("D:/z/Test.xml")
def people = new XmlParser().parse(xmlfile)
people.Plugins.Plugin.findAll { p ->
  if(p.Name.text()=="Super1")
  {
    p.State[0].value="Enabled"
    println(p.State.text())
  }
}
def stringWriter = new StringWriter()
new XmlNodePrinter(new PrintWriter(stringWriter)).print(people)
def newXml = stringWriter.toString()
println("Updated Ec2ConfigService Test xml")
xmlfile.write("<?xml version=\"1.0\" standalone=\"yes\"?>\r\n"+newXml)

XML输入:

<RootNode>
  <Parent>
    <Test>
        <Name>Super1</Name>
        <State>Disabled</State>
    </Test>
    <Test>
        <Name>Super2</Name>
        <State>Disabled</State>
    </Test>
</Parent>

XML输出:

<RootNode>
<Parent>
    <Test>
        <Name>
          Super1
        </Name>
        <State>
          Enabled
        </State>
    </Test>
    ........
</Parent>

例外输出:

<RootNode>
<Parent>
    <Test>
        <Name>Super1</Name>
        <State>Enabled</State>
    </Test>
    ........
</Parent>

此处代码正常工作但更改了元素的排列。如何在不修改对齐的情况下更新元素?

1 个答案:

答案 0 :(得分:0)

您可以按照以下规定执行。

  • 查找Test匹配的Name个节点
  • 然后使用replaceBody替换State
  • 使用地图(用不同的Name替换不同的State
//Added additional node for the tests
def inputXml = '''<RootNode>
  <Parent>
    <Test>
        <Name>Super1</Name>
        <State>Disabled</State>
    </Test>
    <Test>
        <Name>Super2</Name>
        <State>Disabled</State>
    </Test>
    <Test>
        <Name>Super1a</Name>
        <State>Disabled</State>
    </Test>
</Parent>
</RootNode>'''


//Defined map for replacement k, v pair
def changeMap = ['Super1': 'Enabled', 'Super1a': 'Enabled']

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

changeMap.collect { k, v -> def tests = xml.'**'.findAll{it.name() == 'Name' && it == k}*.parent().State*.replaceBody(v) }

println groovy.xml.XmlUtil.serialize(xml)

您可以使用在线 demo

快速尝试相同的操作

如果您使用的是xml文件而不是字符串,则可以使用以下内容:

def xml = new XmlSlurper().parse(new File('D:/z/Test.xml'))

def changeMap = ['Super1': 'Enabled', 'Super1a': 'Enabled']

changeMap.collect { k, v -> def tests = xml.'**'.findAll{it.name() == 'Name' && it == k}*.parent().State*.replaceBody(v) }

println groovy.xml.XmlUtil.serialize(xml)