使用Jsoup替换树中所有文本节点中的文本

时间:2016-09-05 08:05:37

标签: java html jsoup

例如,我们需要在一些html标签内大写所有文本。我可以这样做:

String htmlText = "<h1>Apollo 11</h1><p><strong>Apollo 11</strong> "
            + "was the spaceflight that landed the first humans, Americans <strong>"
            + "<a href=\"http://en.wikipedia.org/wiki/Neil_Armstrong\">Neil Armstrong</a></strong> and... </p>";
Document document = Jsoup.parse(htmlText);
Elements textElements = document.select("h1, p");

for (Element element : textElements) {
        List<TextNode> textNodes = element.textNodes();
        for (TextNode textNode : textNodes){
            textNode.text(textNode.text().toUpperCase());
        }

}
System.out.println(document.html());

结果:<html><head></head><body><h1>APOLLO 11</h1><p><strong>Apollo 11</strong> WAS THE SPACEFLIGHT THAT LANDED THE FIRST HUMANS, AMERICANS <strong><a href="http://en.wikipedia.org/wiki/Neil_Armstrong">Neil Armstrong</a></strong> AND... </p></body></html>

因此,子元素中的所有文本都不是大写的(&lt; strong&gt; Apollo 11&lt; / strong&gt;)。

我可以循环遍历元素并检查节点和子元素,如下所示:

for (Node node : element.childNodes()){
    if (node instanceof TextNode) {
        String nodeText = ((TextNode) node).text();
        nodeText = nodeText.toUpperCase();
        ((TextNode) node).text(nodeText);
    } else {
        String nodeText = ((Element) node).text();
        nodeText = nodeText.toUpperCase();
        ((Element) node).text(nodeText);
    }
}

但是((元素)节点).text()将剪切所有子标签,我们得到:<html><head></head><body><h1>APOLLO 11</h1><p><strong>APOLLO 11</strong> WAS THE SPACEFLIGHT THAT LANDED THE FIRST HUMANS, AMERICANS <strong>NEIL ARMSTRONG</strong> AND... </p></body></html>

注意&#34; NEIL ARMSTRONG&#34;。

上的错过链接标记

我们可以添加另一个内部循环,并检查TextNode和Element,但我不认为这是一个解决方案。

所以我的问题是,如何对某些html树中所有Elements / TextNodes中的文本进行操作并保持所有子标记不变?

1 个答案:

答案 0 :(得分:3)

只需将第一种方法应用于所有选定的节点及其后代:

Elements textElements = document.select("h1, p");

for (Element e : textElements.select("*")) {
    for (TextNode tn : e.textNodes()) {
        tn.text(tn.text().toUpperCase());
    }
}