groovy.util.slurpersupport.NodeChild.appendNode()的意外结果(Groovy 2.2.1)

时间:2014-01-03 01:15:20

标签: groovy xmlslurper

我认为我想要做的很简单:使用XmlSlurper动态地将子节点添加到节点(甚至不知道要添加的节点的名称 - 开发一些框架)。

为了便于解释,可以这样:

def colorsNode = new XmlSlurper().parseText("""
    <colors>
        <color>red</color>
        <color>green</color>
    </colors>""") 

NodeChild blueNode = new XmlSlurper().parseText("<color>blue</color>")  // just for  illustration. The actual contents are all dynamic

colorsNode.appendNode(blueNode) // In real life, I need to be be able to take in any node and append to a given node as child.

我期待结果节点与扼杀以下内容相同:

“””
<colors>
    <color>red</color>
    <color>green</color> 
    <color>blue</color>
</colors>"""

然而,追加的结果是:

colorsNode
    .node
        .children => LinkedList[Node('red') ->   Node('green')   ->   <b>NodeChild</b>(.node='blue')]

换句话说,附加到LinkedList的是NodeChild,它包装新节点,而不是节点本身。

查看NodeChild.java的源代码并不奇怪:

protected void appendNode(final Object newValue) { 
    this.node.appendNode(newValue, this);
}

好吧,我很乐意将我的代码修改为:

colorsNode.appendNode(blueNode<b>.node</b>)

不幸的是NodeChild.node是私有的:(,不知道为什么!实现我正在尝试的东西会有什么好办法吗?我在网上找不到任何解决方案。

我能够通过调整Groovy源并暴露NodeChild.node来完成我的原型设计工作,但现在需要找到一个合适的解决方案。

任何帮助都将不胜感激。

谢谢, Aby Mathew

1 个答案:

答案 0 :(得分:0)

如果您使用XmlParser

会更容易
@Grab('xmlunit:xmlunit:1.1')
import org.custommonkey.xmlunit.Diff
import org.custommonkey.xmlunit.XMLUnit

def xml = """
    <colors>
        <color>red</color>
        <color>green</color>
    </colors>
"""

def expectedResult = """
    <colors>
        <color>red</color>
        <color>green</color>
        <color>blue</color>
    </colors>
"""

def root = new XmlParser().parseText(xml)
root.appendNode("color", "blue")

def writer = new StringWriter()
new XmlNodePrinter(new PrintWriter(writer)).print(root)
def result = writer.toString()

XMLUnit.setIgnoreWhitespace(true)
def xmlDiff = new Diff(result, expectedResult)
assert xmlDiff.identical()