简体   繁体   中英

How to avoid surrounding html head tags in Jsoup parse

Using Jsoup i try to parse the given html content. After Jsoup.parse() the html output append html, head and body tag to the input. I just want to ignore these.

Sample Input:

<p><b>This <i>is</i></b> <i>my sentence</i> of text.</p>

Java code:

import java.io.File;
import java.io.IOException;

import org.apache.commons.io.FileUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class HTMLParse {

    public static void main(String args[]) throws IOException {
        try{
            File input = new File("/ab.html");
            String html = FileUtils.readFileToString(input, null);

            Document doc = Jsoup.parseBodyFragment(html);
            doc.outputSettings().prettyPrint(false);
            System.out.println(doc.html());
        }
        catch(Exception e){
            e.printStackTrace();
        }
    }
}

Actual output:

<html><head></head><body><p><b>This <i>is</i></b> <i>my sentence</i> of text.</p>
    </body></html>

Expected Output:

<p><b>This <i>is</i></b> <i>my sentence</i> of text.</p>

Please help.

The cause:

parseBodyFragment() as well as all other parse() -methods use a HTML parser by default . And those add always the HTML-Shell ( <html>…</html> , <head>…</head> etc.).

The Solution:

Just don't use a HTML-parser, use a XML-parser instead ;-)

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

Replace that single line and your problem is solved.

Example:

final String html = "<p><b>This <i>is</i></b> <i>my sentence</i> of text.</p>";

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

System.out.println("******* HTML *******\n" + docHtml);
System.out.println();
System.out.println("*******  XML *******\n" + docXml);

Output:

******* HTML *******
<html>
 <head></head>
 <body>
  <p><b>This <i>is</i></b> <i>my sentence</i> of text.</p>
 </body>
</html>

*******  XML *******
<p><b>This <i>is</i></b> <i>my sentence</i> of text.</p>

To get the expected output it would actually be:

final String html = "<p><b>This <i>is</i></b> <i>my sentence</i> of text.</p>";
Document doc = Jsoup.parseBodyFragment(html);
doc.outputSettings().prettyPrint(false);

System.out.println(doc.body().html());

You can try using the XML parser, but this doesn't always work because HTML is not always XML; it often has unterminated tags like <img> and <br> . It's better to stick with the HTML parser. You can rely on there being <html> , <head> , and <body> tags and they are easy to discard. Just get your fragment of HTML by selecting the body tag and ask for its HTML.

Document doc = Jsoup.parseBodyFragment(html);
        doc.outputSettings().prettyPrint(false);
        System.out.println(doc.select("body").html());

You can use Jsoup.parse also with HTML parser. All you need to do is to strip the html and body wrappers away.

This can be done by selecting the body element and unwrapping it:

String input = "<p><b>This <i>is</i></b> <i>my sentence</i> of text.</p>";
Node content = Jsoup.parse(input).body().unwrap();
System.out.println(content.html());

By body() you select body element and by unwrap() you remove body and only content remains.

So output is:

<p><b>This <i>is</i></b> <i>my sentence</i> of text.</p>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM