我有一个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
}
答案 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之后就会很好用。
非常感谢蒂姆的原始答案!