5

JSoup 正在转义链接 href 中 URL 查询部分中的与号。鉴于下面的示例

    String l_input = "<html><body>before <a href=\"http://a.b.com/ct.html\">link text</a> after</body></html>";
    org.jsoup.nodes.Document l_doc = org.jsoup.Jsoup.parse(l_input);
    org.jsoup.select.Elements l_html_links = l_doc.getElementsByTag("a");
    for (org.jsoup.nodes.Element l : l_html_links) {
      l.attr("href", "http://a.b.com/ct.html?a=111&b=222");
    }
    String l_output = l_doc.outerHtml();

输出是

    <html>
    <head></head>
    <body>
    before 
    <a href="http://a.b.com/ct.html?a=111&amp;b=222">link text</a> after
    </body>
    </html>

单个 & 被转义到 & . 它不应该保持为 & 吗?

4

2 回答 2

5

看来你做不到。我通过源头找到了逃跑发生的地方。

它在Attribute.java中定义

/**
 Get the HTML representation of this attribute; e.g. {@code href="index.html"}.
 @return HTML
 */
public String html() {
    return key + "=\"" + Entities.escape(value, (new Document("")).outputSettings()) + "\"";
}

在那里你看到它正在使用Entities.java jsoup 采用默认的 outputSettings ,new document("");这样你就不能覆盖这个设置。

也许您应该为此发布功能请求。

顺便说一句:默认的 Escape 模式设置为base

Documet.java创建一个默认对象,并在那里定义它。看:OutputSettings

/**
 * A HTML Document.
 *
 * @author Jonathan Hedley, jonathan@hedley.net 
 */
public class Document extends Element {
    private OutputSettings outputSettings = new OutputSettings();
    // ...
}


/**
 * A Document's output settings control the form of the text() and html() methods.
 */
public static class OutputSettings implements Cloneable {
    private Entities.EscapeMode escapeMode = Entities.EscapeMode.base;
    // ...
}

解决方法(转义为 XML):

通过apache commons langStringEscapeUtils项目,您可以轻松摆脱这些想法。看:

    String unescapedXml = StringEscapeUtils.unescapeXml(l_output);
    System.out.println(unescapedXml);

这将打印:

<html>
 <head></head>
 <body>
  before 
  <a href="http://a.b.com/ct.html?a=111&b=222">link text</a> after
 </body>
</html>

但当然,它将取代所有&amp;...

于 2013-08-23T19:07:36.580 回答
1

Jsoup 所做的实际上是编写 url 的正确方法。例如,如果您编写“id=1©=true”,浏览器可能会将其解释为“id=1©=true”。所以你必须逃避它。

我从https://groups.google.com/forum/#!topic/jsoup/eK4XxHc4Tro得到这个

于 2013-10-31T20:31:42.790 回答