Groovy:使用GPathResult.appendNode(节点)合并两个XML文件不起作用

时间:2017-10-11 19:50:24

标签: xml groovy xmlslurper

我需要编写一个脚本,它接受多个XML文件并根据其内容执行一些操作。为了更容易浏览所有元素,我想将所有文件合并到一个XML树中(仅在内存中)。我尝试使用appendNode()方法,但我遇到了非常奇怪的行为。这是我用来表示问题的片段:

def slurper = new XmlSlurper()
def a = slurper.parseText("<a></a>")
def b = slurper.parseText("<b>foo</b>")
a.appendNode(b)

println XmlUtil.serialize(a)

a."**".each { println (it.name()) }

输出:

<?xml version="1.0" encoding="UTF-8"?><a>
  <b>foo</b>
</a>

a

序列化的XML是正确的,但我没有从迭代器中获得<b>

但是,如果我在追加后添加此行:

a = slurper.parseText(XmlUtil.serialize(a))

输出如下:

<?xml version="1.0" encoding="UTF-8"?><a>
  <b>foo</b>
</a>

a
b

<b>就像我期望的那样。

我在这里缺少什么?为什么再次解析和序列化改变了输出?我是Groovy的新手,所以我想它可能是显而易见的,请帮助我理解它为什么会发生。或者可能有更好的方法来合并XML文件?

1 个答案:

答案 0 :(得分:2)

这是因为XmlSlurper.parse(String text)返回GPathResult,即:

  

用于表示延迟评估的GPath表达式的基类。

根据Groovy XML processing documentation

  

XmlSlurper懒惰地评估结构。因此,如果您更新xml,则必须再次评估整个树。

这就是你必须用

重新评估XML树的原因
a = slurper.parseText(XmlUtil.serialize(a))

让你的表达工作。

另一方面,如果使用XmlParser,则无需重新评估XML树即可使其正常工作,例如

import groovy.xml.XmlUtil

XmlParser root = new XmlParser()
def a = root.parseText("<a></a>")
def b = root.parseText("<b>foo</b>")

a.append(b)

println XmlUtil.serialize(a)

a."**".each { println (it.name()) }

输出

<?xml version="1.0" encoding="UTF-8"?><a>
  <b>foo</b>
</a>

a
b