Вы звоните:
def fun = new ArrayList(root.listofthings.collect{it})
Который устанавливает fun
в качестве узла <listofthings>
(и, кстати, можно сократить до: def fun = root.listofthings
)
Затем в строке:
fun.each {
root.listofthings.appendNode it
}
Вы добавляете этот узел к узлу <listofthings>
.Это означает, что ваше дерево никогда не закончится (поскольку вы присоединяете узел к себе), и, следовательно, StackOverflowException
Чтобы запустить код, вы можете изменить его на:
import groovy.xml.StreamingMarkupBuilder
def xml = """<container>
| <listofthings>
| <thing id="100" name="foo"/>
| </listofthings>
|</container>""".stripMargin()
def root = new XmlSlurper().parseText(xml)
root.listofthings.thing*.replaceNode {}
root.listofthings.appendNode {
thing( id:102, name:'baz' )
}
def outputBuilder = new StreamingMarkupBuilder()
String result = outputBuilder.bind { mkp.yield root }
print result
то есть: избавиться от рекурсивного добавления узла.
Однако я не уверен, что вы пытались сделать с рекурсивным добавлением, так что это, вероятно, не делает то, что вы хотели сделать... Можете ли вы объяснить подробнее, какой результат вы хотели увидеть?
Редактировать
Мне удалось заставить XmlParser делать то, что, как я думаю, вы пытались сделать?
def xml = """<container>
| <listofthings>
| <thing id="100" name="foo"/>
| </listofthings>
|</container>""".stripMargin()
def root = new XmlParser().parseText(xml)
def listofthings = root.find { it.name() == 'listofthings' }
def nodes = listofthings.findAll { it.name() == 'thing' }
listofthings.remove nodes
listofthings.appendNode( 'thing', [ id:102, name:'baz' ] )
nodes.each {
listofthings.appendNode( it.name(), it.attributes(), it.value() )
}
def writer = new StringWriter()
new XmlNodePrinter(new PrintWriter(writer)).print(root)
def result = writer.toString()
print result
Это печатает:
<container>
<listofthings>
<thing id="102" name="baz"/>
<thing id="100" name="foo"/>
</listofthings>
</container>