2013-08-23 178 views
2
我一直在使用下面的代码结构,遍历XML文档

使用DocumentTraversal一个XML元素和它的作品相当不错:递归遍历的Java

import org.w3c.dom.traversal.*; 
... 

private static SomeReturnType traverse(Document doc) { 
    DocumentTraversal dt = (DocumentTraversal) doc; // line-a 
    NodeIterator i = dt.createNodeIterator(doc, NodeFilter.SHOW_ELEMENT, null, false); 
    Node node = i.nextNode(); 
    while (node != null) { 
     // do stuff 
     node = i.nextNode(); 
    } 
    return ... 
} 

但是,怎么可能概括上述允许遍历在文档的随机XML元素中,而不仅仅是整个文档?这在理论上应该很容易,因为在XML中,文档可以被看作是最外层的元素,但是API是反直觉的。

换句话说,你会如何编写上述函数以ElementNode作为参数?

UPDATE

解决方案似乎是:

private static SomeReturnType traverse(Node rootNode) { 
    DocumentTraversal dt = (DocumentTraversal) rootNode.getOwnerDocument(); 
    NodeIterator i = dt.createNodeIterator(rootNode, NodeFilter.SHOW_ELEMENT, null, false); 
    Node node = i.nextNode(); 
    while (node != null) { 
     // do stuff 
     node = i.nextNode(); 
    } 
    return ... 
} 
+0

首先,是不是冒险的假设,即传递的'Document'实现'DocumentTraversal'? javadoc指出:“在支持遍历功能的DOM中,DocumentTraversal将由实现Document接口的相同对象实现。”所以我认为你不可能总是做出这个假设。 –

回答

1

有你的方法采取Node而不是Document。请注意,DocumentTraversal需要Node

1

所以,我实施了一个Iterator/Iterable围绕NodeList包装。它只是使用NodeList.getLength()来确定元素的数量。所以我会做的是通过一个Node的方法和使用Node.getChildNodes()。您可以直接使用NodeList或将其包装在Iterator中。

+0

在这种方法中,您不会获得任何节点的子节点的属性,而文档遍历可以通过SHOW_ALL过滤器来扩展以返回属性。或者我错过了什么?无论如何,我现在有一个实施感谢您删除了以前的答案,所以我不能接受。 –

+0

我为了防止它被删除而删除了它,但似乎是将一个'Node'投射到'DocumentTraversal'的错误假设。 –