Изменить имя XML-тега
Я хочу преобразовать XML-документ, который я проанализировал с XmlSlurper
. (Идентичные) имена тегов XML должны быть заменены значением id
атрибут; все остальные атрибуты должны быть удалены. Начиная с этого кода:
def xml = """<tag id="root">
| <tag id="foo" other="blah" more="meh">
| <tag id="bar" other="huh"/>
| </tag>
|</tag>""".stripMargin()
def root = new XmlSlurper().parseText(xml)
// Some magic here.
println groovy.xml.XmlUtil.serialize(root)
Я хочу получить следующее:
<root>
<foo>
<bar/>
</foo>
</root>
(Я пишу тестовые утверждения на XML и хочу упростить структуру для них.) Я читал обновление XML с помощью XmlSlurper и искал вокруг, но не нашел с replaceNode()
или replaceBody()
для обмена узлом при сохранении его дочерних элементов.
1 ответов
добавление "магии" в код в вопросе дает:
def xml = """<tag id="root">
| <tag id="foo" other="blah" more="meh">
| <tag id="bar" other="huh"/>
| </tag>
|</tag>""".stripMargin()
def root = new XmlSlurper().parseText(xml)
root.breadthFirst().each { n ->
n.replaceNode {
"${n.@id}"( n.children() )
}
}
println groovy.xml.XmlUtil.serialize(root)
, который печатает:
<?xml version="1.0" encoding="UTF-8"?><root>
<foo>
<bar/>
</foo>
</root>
однако это приведет к удалению любого содержимого в узлах. Чтобы поддерживать контент, нам, вероятно, придется использовать рекурсию и XmlParser для создания нового документа из существующего... Я подумаю
более общее решение
Я думаю, что это более обобщенно:
import groovy.xml.*
def xml = """<tag id="root">
| <tag id="foo" other="blah" more="meh">
| <tag id="bar" other="huh">
| something
| </tag>
| <tag id="bar" other="huh">
| something else
| </tag>
| <noid>woo</noid>
| </tag>
|</tag>""".stripMargin()
def root = new XmlParser().parseText( xml )
def munge( builder, node ) {
if( node instanceof Node && node.children() ) {
builder."${node.@id ?: node.name()}" {
node.children().each {
munge( builder, it )
}
}
}
else {
if( node instanceof Node ) {
"${node.@id ?: node.name()}"()
}
else {
builder.mkp.yield node
}
}
}
def w = new StringWriter()
def builder = new MarkupBuilder( w )
munge( builder, root )
println XmlUtil.serialize( w.toString() )
и принты:
<?xml version="1.0" encoding="UTF-8"?><root>
<foo>
<bar>something</bar>
<bar>something else</bar>
<noid>woo</noid>
</foo>
</root>
сейчас проходит через узлы без (или пустые)id
атрибуты