2016-04-14 1615 views
3

我试图用Jsoup遍历DOM的节点,并在满足条件时删除一些节点及其子节点。不过,我这样做的例外是java.lang.NullPointerException。我有类似:Jsoup在遍历时删除节点和子节点

File input = new File(inputPath); 
Document doc = Jsoup.parse(input, "UTF-8"); 

doc.traverse(new NodeVisitor() { 

    @Override 
    public void head(Node node, int depth) { 

     switch (node.getClass().getName()){ 

     case "org.jsoup.nodes.Element": 

      Element elem = (Element) node; 
      Map<String, String> dataset = elem.dataset(); 
      for (String key : dataset.keySet()) { 

       ..... 

       // Here is the problem 
       if (someCondition) node.remove() 
      } 
      break; 

     case "org.jsoup.nodes.TextNode": 

      .... 
      break; 
     } 
    } 

    @Override 
    public void tail(Node node, int depth) { 

    } 
}); 

不知怎的,它是有道理的,它不会让我删除节点,而迭代他们,但是这将是实现这一目标,则方法是什么?遍历DOM时移除节点及其子节点?

回答

2

删除headtail中的节点将无法可靠地工作(实际上,它似乎取决于您删除的节点)。您可以简单地将引用存储到要删除的节点,然后再处理它们,而不是在遍历时删除。

List<Node> toRemove = new LinkedList<>(); 
doc.traverse(new NodeVisitor() { 
    @Override 
    public void head(Node node, int depth) { 
     // ... 
     if(condition) 
      toRemove.add(node); 
    } 
    // ... 
}); 

for (Node node : toRemove) 
    node.remove(); 

样品上方应该工作,即使你删除所有非根节点。

+0

是的,这实际上是我最终做的最后... – houcros

0

只是猜测:尝试在遍历方法的末尾删除节点。或者,每次删除它时重新开始遍历。