在Jsoup中如何在迭代期间更改/拆分节点

时间:2014-11-03 14:48:59

标签: java regex jsoup

我正在使用包含文档的html文件。在解析期间,我将拆分textnode,这会导致并发修改错误。

private void processInContent(Node ele) {
        String text = "";        
        for (Node child : ele.childNodes()) {            
            Node parentNode = child.parentNode();
            if (child instanceof TextNode && !("a").equalsIgnoreCase(parentNode.nodeName())) {
                TextNode childText = (TextNode) child;
                text = childText.text();
                System.out.println(text);
                Matcher m = pattern.matcher(text);
                while (m.find()) {
                    String matched = null;
                    boolean url = false;
                    if (m.group(2) != null) {
                        matched = m.group(6);

                    } else {
                        break;
                    }
                    text = childText.text();
                    TextNode replaceNode = childText.splitText(text.indexOf(matched));
                    TextNode lastNode = replaceNode.splitText(matched.length());                    
                    Element anchorEle = ele.ownerDocument().createElement("a");
                    anchorEle.attr("href", "mailto:" + matched);

                    anchorEle.attr("target", "_blank");
                    anchorEle.text(matched);
                    replaceNode.replaceWith(anchorEle);                    
                    childText = lastNode;
                }
            }
        }
    }

示例内容

 <div id="abc"><br>---- The email address is abc@abc.com</b> contains abc
 domain email address <br></div>

我想为电子邮件地址添加锚标记,导致以下异常

java.util.ConcurrentModificationException
        at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
        at java.util.AbstractList$Itr.next(AbstractList.java:343)
        at java.util.Collections$UnmodifiableCollection$1.next(Collections.java:1008)
        at JSOUPParse.processInContent(JSOUPParse.java:253)
        at JSOUPParse.main(JSOUPParse.java:318)

请帮我解决这个问题。

1 个答案:

答案 0 :(得分:3)

问题是由于您在遍历它们时向Node ele添加节点而引起的。这是非法的,这就是java.util.ConcurrentModificationException的意思。

您可以在循环for (Node child : ele.childNodes())中存储要处理的节点,然后可以在另一个循环中进行修改。

private void processInContent(Node ele) {
    String text = "";        

    ArrayList<Node> toReplace = new ArrayList<Node>();
    for (Node child : ele.childNodes()) {            
        Node parentNode = child.parentNode();
        if (child instanceof TextNode && !("a").equalsIgnoreCase(parentNode.nodeName())) {
            toReplace.add(child);
        }
    }
    for (Node child : toReplace){
        TextNode childText = (TextNode) child;
        text = childText.text();
        Matcher m = pattern .matcher(text);
        while (m.find()) {
            // more code .........
            Element anchorEle = ele.ownerDocument().createElement("a");
            // more code .........
        }
    }
}

此代码不会抛出ConcurrentModificationException

希望它有所帮助。