【问题标题】:how to unescape html entities **except** &lt; &gt; &amp; &quot; &apos; in javajava - 如何在java中取消转义html实体**除了** < > &“”
【发布时间】:2018-08-16 14:18:38
【问题描述】:

我在 utf-8 中有 html 输入。在此输入中,重音字符显示为 html 实体。例如:

<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>&aacute;rv&iacute;zt&#x0171;r&#x0151;&lt;b</body>
</html>

我的目标是通过在 Java 中尽可能用 utf-8 字符替换 html 实体来“规范化”html。换句话说,替换所有实体除了 &amp;lt; &amp;gt; &amp;amp; &amp;quot; &amp;apos;

目标:

<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>árvíztűrő&lt;b</body>
</html>

我需要它以便更容易在测试中比较 html,并且更容易用肉眼阅读(大量转义的重音字符使其难以阅读)。

我不关心 cdata 部分(输入中没有 cdata)。

我尝试过 JSOUP (https://jsoup.org/) 和 Apache 的 Commons Text (https://commons.apache.org/proper/commons-text/) 均未成功:

public void test() throws Exception {

    String html = 
            "<html><head><META http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">" +
            "</head><body>&aacute;rv&iacute;zt&#x0171;r&#x0151;&lt;b</body></html>";

    // this is not good, keeps only the text content
    String s1 = Jsoup.parse(html).text();
    System.out.println("s1: " + s1);

    // this is better, but it unescapes the &lt; which is not what I want
    String s2 = StringEscapeUtils.unescapeHtml4(html);
    System.out.println("s2: " + s2);
}

StringEscapeUtils.unescapeHtml4() 几乎是我所需要的,但不幸的是它使

<body>árvíztűrő<b</body>

我该怎么做?

这是一个最小的演示:https://github.com/riskop/html_utf8_canon.git

【问题讨论】:

    标签: java html escaping html-entities


    【解决方案1】:

    查看 Commons Text 源代码,很明显 StringEscapeUtils.unescapeHtml4() 将工作委托给 AggregateTranslator,它由 4 个 CharSequenceTranslator 组成:

    new AggregateTranslator(
            new LookupTranslator(EntityArrays.BASIC_UNESCAPE),
            new LookupTranslator(EntityArrays.ISO8859_1_UNESCAPE),
            new LookupTranslator(EntityArrays.HTML40_EXTENDED_UNESCAPE),
            new NumericEntityUnescaper()
    );
    

    我需要只需要三个翻译来实现我的目标。

    原来如此:

        // this is what I needed!
        String s3 = new AggregateTranslator(
                new LookupTranslator(EntityArrays.ISO8859_1_UNESCAPE),
                new LookupTranslator(EntityArrays.HTML40_EXTENDED_UNESCAPE),
                new NumericEntityUnescaper()
        ).translate(html);
        System.out.println("s3: " + s3);
    

    整个方法:

    @Test
    public void test() throws Exception {
    
        String html = 
                "<html><head><META http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">" +
                "</head><body>&aacute;rv&iacute;zt&#x0171;r&#x0151;&lt;b</body></html>";
    
        // this is what I needed!
        CharSequenceTranslator UNESCAPE_HTML_EXCEPT_BASIC = new AggregateTranslator(
                new LookupTranslator(EntityArrays.ISO8859_1_UNESCAPE),
                new LookupTranslator(EntityArrays.HTML40_EXTENDED_UNESCAPE),
                new NumericEntityUnescaper()
        );
    
        String s3 = UNESCAPE_HTML_EXCEPT_BASIC.translate(html);
        System.out.println("s3: " + s3);
    
    }
    

    结果:

    <html>
    <head>
    <META http-equiv="Content-Type" content="text/html; charset=utf-8">
    </head>
    <body>árvíztűrő&lt;b</body>
    </html>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-14
      相关资源
      最近更新 更多