Java:迭代org.w3c.dom.Document中所有元素的最有效方法?

KJW*_*KJW 70 java xml iteration dom

迭代Java中所有DOM元素的最有效方法是什么?

这样的东西,但对于当前的每个DOM元素org.w3c.dom.Document

for(Node childNode = node.getFirstChild(); childNode!=null;){
    Node nextChild = childNode.getNextSibling();
    // Do something with childNode, including move or delete...
    childNode = nextChild;
}
Run Code Online (Sandbox Code Playgroud)

jav*_*nna 122

基本上,您有两种方法可以迭代所有元素:

1.使用递归(我认为最常见的方式):

public static void main(String[] args) throws SAXException, IOException,
        ParserConfigurationException, TransformerException {

    DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
        .newInstance();
    DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
    Document document = docBuilder.parse(new File("document.xml"));
    doSomething(document.getDocumentElement());
}

public static void doSomething(Node node) {
    // do something with the current node instead of System.out
    System.out.println(node.getNodeName());

    NodeList nodeList = node.getChildNodes();
    for (int i = 0; i < nodeList.getLength(); i++) {
        Node currentNode = nodeList.item(i);
        if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
            //calls this method for all the children which is Element
            doSomething(currentNode);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

2.使用getElementsByTagName()*参数的方法避免递归:

public static void main(String[] args) throws SAXException, IOException,
        ParserConfigurationException, TransformerException {

    DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
            .newInstance();
    DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
    Document document = docBuilder.parse(new File("document.xml"));

    NodeList nodeList = document.getElementsByTagName("*");
    for (int i = 0; i < nodeList.getLength(); i++) {
        Node node = nodeList.item(i);
        if (node.getNodeType() == Node.ELEMENT_NODE) {
            // do something with the current element
            System.out.println(node.getNodeName());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我认为这些方法都很有效.
希望这可以帮助.

  • 我认为现在避免堆栈溢出为时已晚.你已经在这里了. (122认同)
  • 将迭代索引作为参数传递给递归函数,您可以使其为尾递归(由编译器优化),以避免堆栈溢出. (11认同)

And*_*rew 37

for (int i = 0; i < nodeList.getLength(); i++)

改成

for (int i = 0, len = nodeList.getLength(); i < len; i++)

更有效率.

javanna回答的第二种方式可能是最好的,因为它倾向于使用更平坦,可预测的记忆模型.