我想从 XML 元素中删除空节点。此 xml 是从供应商生成的,我无法控制 xml 生成。但是由于 XML 几乎没有空节点,我需要递归地删除这些空节点。
这个 xml 是从 OMElement 得到的,我使用 [XMLUtils][1] Sample XML 从这个对象得到一个 Element
<A>
<B>
<C>
<C1>
<C11>something</C11>
<C12>something</C12>
</C1>
</C>
<D>
<D1>
<D11>
<D111 operation="create">
<Node>something else</Node>
</D11>
</D11>
</D1>
<D2>
<D21>
</D21>
</D2>
</D>
</B>
</A>
Run Code Online (Sandbox Code Playgroud)
由于 D21 是一个空节点,我想删除 D21,而现在 D2 是一个空节点,我想删除 D2,但由于 D 有 D1,我不想删除 D。
同样,我有可能得到
<A>
<B>
<C>
</C>
</B>
</A>
Run Code Online (Sandbox Code Playgroud)
现在因为 C 是空的,我想删除 C,然后是 B,最后是节点 A。我试图在Node 中使用 removeChild() 方法来做到这一点
但到目前为止,我无法递归删除它们。有什么建议可以递归删除它们吗?
我递归地尝试获取节点和节点长度。但是节点长度没有帮助
if(childNode.getChildNodes().getLength() == 0 ){
childNode.getParentNode().removeChild(childNode);
}
Run Code Online (Sandbox Code Playgroud)
问候
Dheeraj Joshi
我没有足够的代表来评论@Adam 的解决方案,但我遇到了一个问题,在删除节点后,该节点的最后一个兄弟节点被移动到索引零,导致它无法完全删除空元素。修复方法是使用一个列表来保存我们想要递归调用删除的所有节点。
此外,还有一个错误会删除具有属性的空元素。
两个问题的解决方法:
public static void removeEmptyNodes(Node node) {
NodeList list = node.getChildNodes();
List<Node> nodesToRecursivelyCall = new LinkedList();
for (int i = 0; i < list.getLength(); i++) {
nodesToRecursivelyCall.add(list.item(i));
}
for(Node tempNode : nodesToRecursivelyCall) {
removeEmptyNodes(tempNode);
}
boolean emptyElement = node.getNodeType() == Node.ELEMENT_NODE
&& node.getChildNodes().getLength() == 0;
boolean emptyText = node.getNodeType() == Node.TEXT_NODE
&& node.getNodeValue().trim().isEmpty();
if (emptyElement || emptyText) {
if(!node.hasAttributes()) {
node.getParentNode().removeChild(node);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是可行的,只需创建一个首先“深入”的递归函数,然后在“备份树”的过程中删除空节点,这将具有删除 D21 和 D2 的效果。
public static void main(String[] args) throws Exception {
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
String input = "<A><B><C><C1><C11>something</C11><C12>something</C12></C1></C><D><D1><D11><D111 operation=\"create\"><Node>something else</Node></D111></D11></D1><D2><D21></D21></D2></D></B></A>";
Document document = builder.parse(new InputSource(new StringReader(
input)));
removeNodes(document);
Transformer transformer = TransformerFactory.newInstance()
.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
StreamResult result = new StreamResult(new StringWriter());
transformer.transform(new DOMSource(document), result);
System.out.println(result.getWriter().toString());
}
public static void removeNodes(Node node) {
NodeList list = node.getChildNodes();
for (int i = 0; i < list.getLength(); i++) {
removeNodes(list.item(i));
}
boolean emptyElement = node.getNodeType() == Node.ELEMENT_NODE
&& node.getChildNodes().getLength() == 0;
boolean emptyText = node.getNodeType() == Node.TEXT_NODE
&& node.getNodeValue().trim().isEmpty();
if (emptyElement || emptyText) {
node.getParentNode().removeChild(node);
}
}
Run Code Online (Sandbox Code Playgroud)
输出
<A>
<B>
<C>
<C1>
<C11>something</C11>
<C12>something</C12>
</C1>
</C>
<D>
<D1>
<D11>
<D111 operation="create">
<Node>something else</Node>
</D111>
</D11>
</D1>
</D>
</B>
</A>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18941 次 |
| 最近记录: |