我需要编写一个脚本,它接受多个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文件?
答案 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