groovy - 更改 XML 标签名称

标签 groovy xmlslurper

我想转换一个用 XmlSlurper 解析的 XML 文档。 (相同的)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 上编写测试断言,并希望简化它们的结构。)我已阅读 Updating XML with XmlSlurper并四处搜索,但发现无法使用 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)

打印内容:

<?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 属性的节点

关于groovy - 更改 XML 标签名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14937816/

相关文章:

Groovy XmlSlurper 获取没有子节点的节点的值

XmlSlurper.appendNode 不改变大小

java - 充满反射调用的常规应用程序的 CPU 分析器结果

java - Groovy 可以复制类签名但修改实现吗

xml - 在 Groovy 中对 XML 进行排序

grails - 如何在Groovy中查找具有特定属性值的节点的文本?

python - 如何最好地从 groovy 中的键列表/值列表中获取 map ?

groovy - Groovy 编译器如何工作?

gradle - Micronaut @Scheduled 作业未运行

xml - Groovy - XmlSlurper - 将属性读入 map