7

XML 要素から空のノードを削除したいと考えています。この xml はベンダーから生成されたものであり、私は xml 生成を制御できません。しかし、XML には空のノードがほとんどないため、それらの空のノードを再帰的に削除する必要があります。

この xml は OMElement から取得され、[XMLUtils][1] サンプル XML を使用してこのオブジェクトから要素を取得します

<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> 

D21 は空のノードであるため、D21 を削除したいのですが、D2 は空のノードであるため、D2 を削除したいのですが、D には D1 があるため、D を削除したくありません。

同様に、私が得ることができる可能性があります

<A>
  <B>
    <C>

    </C>
  </B>
</A>

C は空なので、C を削除してから B を削除し、最終的にノードA を削除します。Node で removeChild() メソッドを使用してこれを実行しようとしています。

しかし、これまでのところ、それらを再帰的に削除することはできません。それらを再帰的に削除するための提案はありますか?

ノードとノードの長さを再帰的に取得しようとしています。しかし、ノードの長さは役に立ちません

if(childNode.getChildNodes().getLength() == 0 ){
       childNode.getParentNode().removeChild(childNode);

               }

よろしく
ディーラジ・ジョシ

4

5 に答える 5

4

これは機能します。最初に「深く掘り下げ」、次に「ツリーをバックアップ」する途中で空のノードを削除する再帰関数を作成するだけで、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);
    }
}

出力

<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>
于 2012-09-21T07:02:11.107 に答える
2

getTextContent()DOM の最上位要素で使用します。メソッドが空の文字列または null を返す場合、このノードとすべての子ノードが空であるため、このノードを削除できます。メソッドgetTextContent()が空の文字列を返さない場合getTextContentは、現在のノードのすべての子を呼び出します。ドキュメント
を参照してください。

于 2012-09-21T06:58:58.230 に答える