Groovy 更改XML标记名
我想转换用Groovy 更改XML标记名,groovy,xmlslurper,Groovy,Xmlslurper,我想转换用XmlSlurper解析的XML文档。(相同的)XML标记名应替换为id属性的值;应删除所有其他属性。从这个代码开始: defxml=”“” | | | |“.stripMargin() def root=new XmlSlurper().parseText(xml) //这里有些魔力。 println groovy.xml.XmlUtil.serialize(根) 我想得到以下信息: (我在XML上编写测试断言,并希望简化它们的结构。)我已经阅读和搜索过了,
XmlSlurper
解析的XML文档。(相同的)XML标记名应替换为id
属性的值;应删除所有其他属性。从这个代码开始:
defxml=”“”
|
|
|
|“.stripMargin()
def root=new XmlSlurper().parseText(xml)
//这里有些魔力。
println groovy.xml.XmlUtil.serialize(根)
我想得到以下信息:
(我在XML上编写测试断言,并希望简化它们的结构。)我已经阅读和搜索过了,但没有找到使用
replaceNode()
或replaceBody()
在保留子节点的同时交换节点的方法。在问题中的代码中添加“魔力”给出:
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)
defxml=”“”
|
|
|
|“.stripMargin()
def root=new XmlSlurper().parseText(xml)
root.breadthFirst()。每个{n->
n、 替换节点{
“${n.@id}”(n.children())
}
}
println groovy.xml.XmlUtil.serialize(根)
其中打印:
<?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() )
导入groovy.xml*
def xml=“”
|
|
|某物
|
|
|别的
|
|求爱
|
|“.stripMargin()
def root=new XmlParser().parseText(xml)
def munge(生成器、节点){
if(node&&node.children()的节点实例){
生成器“${node@id?:node.name()}”{
node.children()。每个{
芒奇(建筑商,it)
}
}
}
否则{
if(节点的节点实例){
“${node@id?:node.name()}”()
}
否则{
builder.mkp.yield节点
}
}
}
def w=新的StringWriter()
def生成器=新的标记生成器(w)
munge(生成器,根)
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
属性的节点我假设一些标记也有内容?如果没有,您可以执行:root.breadthFirst().each{n->n.replaceNode{“${n.@id}”(n.children())}
,但这将丢失nodes@tim_yates:目前,没有内容,因此您的解决方案(尽管不完整)已适用于我。请将其作为答案发布!完成:-)我会考虑一个更一般化的递归函数非常感谢你的回答;我渴望看到一个通用的解决方案。在快速测试后,添加了一个更通用的解决方案
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>