Groovy 从节点中删除空属性和空子级

Groovy 从节点中删除空属性和空子级,groovy,Groovy,我有一个函数,我想在将其写入文件之前,递归地删除所有null属性和空子级。我下面的方法很有效,但似乎应该有一个内置的方法。我错过什么了吗 Node cleanNode(Node node) { // Find null attributes def attributesToRemove = [] for(e in node.attributes()) { if(e.value == null) { attributesToRemo

我有一个函数,我想在将其写入文件之前,递归地删除所有
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
}

据我所知,没有一种内置的方法可以实现这一点。。。您可以使代码稍微小一些(并递归地删除空的子项),如下所示:

因此,考虑到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()
其中:

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

求爱
你好

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

如果xml包含名称空间,则
cleanNode
方法将导致在每个节点上喷洒名称空间声明。 为了避免这种情况,请使用新的XmlParser(false,false),这样代码就变成:

Node root = new XmlParser(false, false).parseText(xml)
cleanNode(root)
println XmlUtil.serialize(root)
通过这种方式,xml变得很好,并且在之后变得干净


非常感谢Tim给出的原始答案

您的
cleanNode
方法非常棒@ubiquibacon对
属性
/
子类
bug(哎哟)我注意到的另一件事是您对
使用了“Groovy truth”!it.value
。这可能适用于大多数阅读本文的人,因此我没有在您的答案中对其进行编辑,但对我来说,我必须使用
it.value==null
,因为我有值为零的属性。它们不是包含
'0'
的字符串吗?不一定,在创建节点时可以将
int
作为属性值。
<?xml version="1.0" encoding="UTF-8"?><root>
  <body>
    <h1 title="title">woo</h1>
  </body>
  <tail>
    <item>hi</item>
  </tail>
</root>
Node root = new XmlParser(false, false).parseText(xml)
cleanNode(root)
println XmlUtil.serialize(root)