Неожиданные результаты с groovy.util.slurpersupport.NodeChild.appendNode() (Groovy 2.2.1)

Я думаю, что я пытаюсь сделать просто: динамически добавлять дочерние узлы к узлу (даже не зная имени добавляемого узла - разрабатывая какую-то инфраструктуру), используя 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, но теперь нужно найти правильное решение.

Любая помощь будет оценена.

Спасибо, Эйби Мэтью

1 ответ

Было бы проще, если вы используете 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()
Другие вопросы по тегам