Jsoup - 仅保留标签并删除所有文本

时间:2014-06-18 16:56:29

标签: java html jsoup

我正在尝试使用Jsoup

删除HTML页面标记之间的所有文本

例如,如果输入HTML是

<!DOCTYPE html>
<html>
<body>
<h1>My First Heading</h1>
<p>My first paragraph.</p>
</body>
</html>

输出应为

<!DOCTYPE html>
<html>
<body>
<h1></h1>
<p></p>
</body>
</html>

基本上,我想删除doc.text()

返回的内容

我发现很多帖子都是相反的,只保留文字,但没有什么可以解决我的问题。关于如何做到这一点的任何想法?

修改

maverick9999提出的解决方案:https://stackoverflow.com/a/24292349/3589481将解决大多数情况。

但是,正如评论中所注意到的,此解决方案还将删除嵌套标记。

举个例子:

    String str = "<!DOCTYPE html>" +
                "<html>" +
                "<body>" +
                "<div class='foo'>text <div class='THIS DIV WILL BE REMOVED'>text</div> text </div>" +
                "<h1>My First Heading</h1>\n" +
                "<p>My first paragraph.</p>\n" +
                "</body>\n" +
                "</html>";

        Document doc=Jsoup.parse(str);
        removeAllTexts(doc);
        System.out.println(doc);

        Elements all=doc.select("*");
        Iterator<Element>iterator=all.iterator();
        while(iterator.hasNext()){
            Element e=iterator.next();
            if(!e.ownText().isEmpty()){
                e.text("");
            }
        }

        System.out.println(doc);

将删除输出中的一个div:

    <html>
     <head></head>
     <body>
      <div class="foo">
      </div>
     </body>
    </html>

有什么想法可以避免这种情况吗?

编辑2

出于某种原因,标签&#34; meta&#34;被Jsoup视为自我关闭。 所以,如果你有这样的事情:

System.out.println("\n\n----");
String html = "<!DOCTYPE html>\r\n"
+ "<html>\r\n"
+ "<head>\n" 
+ "<meta content=\"/myimage.png\" itemprop=\"image\">\n"
+ "<title>Title</title>\n" 
+ "<script>Random Javascript here</script>"
+ "</meta>"
+ "</head>"
+ "<body>\r\n"
+ "<h1>My First <i>Heading</i></h1>\r\n"
+ "<hr/>\r\n"
+ "<p>My first paragraph.</p>\r\n"
+ "<p> <div class='foo'>text <div class='bar'> text </div> text </div> </p>\r\n"
+ "</body>\r\n" 
+ "</html>";

Document doc2 = Jsoup.parse(html,"",Parser.xmlParser());
printNodes(doc2);

然后将不会读取meta之后的所有标签。使用Pshemo解决方案,脚本将被删除,如果您有br个带子项的标签(例如),它们也将被删除。 我最终得到了以下解决方案(感谢Pshemo的帮助):

   public static void printNodes(Node node) {
        String name = node.nodeName();
        if (name.equals("#doctype")) {
            System.out.println(node);
        } else if (name.equals("#text")) {
            return;
        } else if (name.equals("#document")) {
            for (Node n : node.childNodes())
                printNodes(n);
        } 
        // There is no reason to have text here, so print everything
        else if (name.equals("head") || name.equals("script")){
            System.out.println(node.toString());
        }
        else {
            if (!Tag.valueOf(name).isSelfClosing() || node.childNodeSize()>0) {
                System.out.println("<" + name + getAttributes(node) + ">");
                for (Node n : node.childNodes())
                    printNodes(n);
                System.out.println("</" + name + ">");
            } else {
                // System.out.println("debug: " + name + " is self closing");
                System.out.println("<" + name + getAttributes(node) + "/>");
            }
        }
    }

   public static String getAttributes(Node node) {
        StringBuilder sb = new StringBuilder();
        for (Attribute attr : node.attributes()) {
            sb.append(" ").append(attr.getKey()).append("=\"")
                    .append(attr.getValue()).append("\"");
        }
        return sb.toString();
    }

1 个答案:

答案 0 :(得分:6)

以下代码可以解决嵌套标记的问题:

更新的代码:

Document doc = Jsoup.parse(html, "", Parser.xmlParser());

for (Element el : doc.select("*")){
    if (!el.ownText().isEmpty()){
        for (TextNode node : el.textNodes())
            node.remove();
    }
}

System.out.println(doc);