一、问题描述
在Jsoup生成的HTML中,自闭合标签(如<link>
、<meta>
等)会根据HTML的标准格式进行输出,有时会省略自闭合的斜杠。这虽然不会影响浏览器的解析,但在一些特殊场景下会导致解析失败,例如epub格式文件。
原文件内容:
<?xml version='1.0' encoding='utf-8'?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>这是一个标题</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link href="stylesheet.css" rel="stylesheet" type="text/css" />
<link href="page_styles.css" rel="stylesheet" type="text/css" />
</head>
</html>
Jsoup生成的内容
<?xml version='1.0' encoding='utf-8'?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>这是一个新的标题</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link href="stylesheet.css" rel="stylesheet" type="text/css">
<link href="page_styles.css" rel="stylesheet" type="text/css">
</head>
</html>
可以看到<link>
、<meta>标签的自闭合斜杠被省略了。
二、解决方法
可以使用Jsoup的OutputSettings
类来控制输出格式,实现方式如下:
public static void main(String[] args) {
String html = "<?xml version='1.0' encoding='utf-8'?>\n" +
"<html xmlns=\"http://www.w3.org/1999/xhtml\">\n" +
"\n" +
"<head>\n" +
" <title>这是一个标题</title>\n" +
" <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n" +
" <link href=\"stylesheet.css\" rel=\"stylesheet\" type=\"text/css\" />\n" +
" <link href=\"page_styles.css\" rel=\"stylesheet\" type=\"text/css\" />\n" +
"</head>\n" +
"\n" +
"</html>";
Document doc = Jsoup.parse(html);
// 替换 <title> 标签内容
Element title = doc.selectFirst("title");
if (title != null) {
title.text("这是一个新的标题");
}
// 设置输出格式
OutputSettings settings = new OutputSettings();
settings.syntax(OutputSettings.Syntax.xml);
doc.outputSettings(settings);
System.out.println(doc.toString());
}
在以上示例中,通过设置OutputSettings
为Syntax.xml
,我们确保自闭合标签在输出时保留斜杠。运行这个程序将输出:
<!--?xml version='1.0' encoding='utf-8'?-->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>这是一个新的标题</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link href="stylesheet.css" rel="stylesheet" type="text/css" />
<link href="page_styles.css" rel="stylesheet" type="text/css" />
</head>
<body></body>
</html>