从Node中删除null属性和空子项

时间:2013-12-04 23:21:38

标签: groovy

我有一个Node我要删除所有null属性并在将其写入文件之前以递归方式清空子项。我在下面的工作,但似乎应该有一个内置的方法。我错过了什么吗?

Node cleanNode(Node node) {

    // Find null attributes
    def attributesToRemove = []
    for(e in node.attributes()) {
        if(e.value == null) {
            attributesToRemove.add(e.key)
        }
    }

    // Remove null attributes
    for(attribute in attributesToRemove) {
        node.attributes().remove(attribute)
    }

    // Clean this node's children
    for(child in node.children()) {
        if(child instanceof Node) {
            cleanNode(child)
        }
    }

    // If node has no attributes, no children, and no text then discard it by setting it to null
    if(!node.attributes() && !node.children() && !node.text()) {
        node = null
    }

    node
}

2 个答案:

答案 0 :(得分:6)

我知道没有用于实现此目的的构建方法......您可以将代码缩小(并递归删除空子代码),如下所示:

boolean cleanNode( Node node ) {
    node.attributes().with { a ->
        a.findAll { !it.value }.each { a.remove( it.key ) }
    }
    node.children().with { kids ->
        kids.findAll { it instanceof Node ? !cleanNode( it ) : false }
            .each { kids.remove( it ) }
    }
    node.attributes() || node.children() || node.text()
}

所以给出了xml:

def xml = '''<root>
            |  <head>
            |    <item>
            |       <woo/>
            |    </item>
            |  </head>
            |  <body att=''>
            |    <h1 name='' title='title'>
            |      woo
            |    </h1>
            |  </body>
            |  <tail>
            |    <item>hi</item>
            |  </tail>
            |</root>'''.stripMargin()

我们可以解析并清理并打印出来:

Node root = new XmlParser().parseText( xml )
cleanNode( root )
println XmlUtil.serialize( root )

给出:

<?xml version="1.0" encoding="UTF-8"?><root>
  <body>
    <h1 title="title">woo</h1>
  </body>
  <tail>
    <item>hi</item>
  </tail>
</root>

如您所见,整个<head>块已被清除,因为它不包含任何信息。

答案 1 :(得分:1)

如果xml包含名称空间,cleanNode方法将导致名称空间声明喷射到每个节点上。 为避免这种情况使用new XmlParser(false, false),代码变为:

Node root = new XmlParser(false, false).parseText(xml)
cleanNode(root)
println XmlUtil.serialize(root)

这样,xml之后就会很好用。

非常感谢蒂姆的原始答案!