jsoup 是一款非常优秀的处理HTML的java工具,最大的特点就是拥有类似jquery的select操作。使用非常简单,但是最近本人在使用过程中,由于不熟悉踩了一个坑,记录已备忘。
代码如下:
public static void main(String[] args) {
String content = "<a href=\"test.html\" title=\"men tshirt\" >men tshirt</a>";
try {
Document document = Jsoup.parse(content);
Elements links = document.select("a");
for (Element link : links) {
link.attr("clickdata", "adfafgadsfaf");
if (!link.hasClass("click-target-with-quot")) {
link.addClass("click-target-with-quot");
}
}
System.out.println(document.html());// 错误代码
System.out.println(document.body().html());//正确代码
} catch (Exception e) {
}
}
需求也很简单,将一个HTML片段中的所有的<a>标签,增加一个class,和一个自定义属性。
代码中红色标注了错误和正确的代码,区别在于错误的代码会返回添加了<html>等头尾的标签。
<html>
<head></head>
<body>
<a href="test.html" title="men tshirt" clickdata="adfafgadsfaf" class=" click-target-with-quot">men tshirt</a>
</body>
</html>
正确的如下:
<a href="test.html" title="men tshirt" clickdata="adfafgadsfaf" class=" click-target-with-quot">men tshirt</a>
原因在于:在 Jsoup.parse解析的时候在类HtmlTreeBuilderState类中会判断是否属于BeforeHtml,BeforeHead等等状态,如果满足的话会被强制添加<html>标签。
具体代码如下:
BeforeHtml {
boolean process(Token t, HtmlTreeBuilder tb) {
if (t.isDoctype()) {
tb.error(this);
return false;
} else if (t.isComment()) {
tb.insert(t.asComment());
} else if (isWhitespace(t)) {
return true; // ignore whitespace
} else if (t.isStartTag() && t.asStartTag().name().equals("html")) {
tb.insert(t.asStartTag());
tb.transition(BeforeHead);
} else if (t.isEndTag() && (StringUtil.in(t.asEndTag().name(), "head", "body", "html", "br"))) {
return anythingElse(t, tb);
} else if (t.isEndTag()) {
tb.error(this);
return false;
} else {
return anythingElse(t, tb);
}
return true;
}
private boolean anythingElse(Token t, HtmlTreeBuilder tb) {
tb.insert("html");
tb.transition(BeforeHead);
return tb.process(t);
}
}
本站支持 pay for your wishes