1

这是输入:

<div>The price is &lt; 5 &euro;</div>

它是有效的 HTML,但不是有效的 XML(因为&euro;未在 DTD 中声明)。有效的 XML 如下所示:

<div>The price is &lt; 5 &#8364;</div>

你能推荐一些 Java 库来帮助我对 HTML 实体进行转义并将它们转换为 XML 实体吗?

4

2 回答 2

3

使用 apache commons lang 3,一个只替换 HTML 特定实体的类:

import org.apache.commons.text.translate.AggregateTranslator;
import org.apache.commons.text.translate.CharSequenceTranslator;
import org.apache.commons.text.translate.EntityArrays;
import org.apache.commons.text.translate.LookupTranslator;
import org.apache.commons.text.translate.NumericEntityUnescaper;


public class HtmlEscapeUtils {

  /**
   * @see {@link org.apache.commons.text.StringEscapeUtils#UNESCAPE_HTML4}
   */
  public static final CharSequenceTranslator UNESCAPE_HTML_SPECIFIC =
      new AggregateTranslator(
          new LookupTranslator(EntityArrays.ISO8859_1_UNESCAPE),
          new LookupTranslator(EntityArrays.HTML40_EXTENDED_UNESCAPE),
          new NumericEntityUnescaper());


  /**
   * @see {@link org.apache.commons.text.StringEscapeUtils#unescapeHtml4(String)}
   * @param input - HTML String with e.g. &quot; &amp; &auml;
   * @return XML String, HTML4 Entities replaced, but XML Entites remain (e.g. &quot; und &amp;)
   */
  public static final String unescapeHtmlToXml(final String input) {
    return UNESCAPE_HTML_SPECIFIC.translate(input);
  }

}
于 2020-01-16T10:36:59.323 回答
1

所有 HTML 命名字符引用的列表可在http://www.whatwg.org/specs/web-apps/current-work/multipage/entities.json获得

如果您可以容忍偶尔出现的错误,您可以检查该文件并将独立 XML 中不允许的所有命名字符引用替换为相应的数字字符引用。

如果您的输入是 HTML,而不是 XHTML,那么这种简单的方法可能会遇到问题:

<script>var y=1, lt = 3, x = y&lt; alert(x);</script>

包含一个脚本元素,其内容未使用实体进行编码,因此天真地替换&lt;此处将破坏脚本。还有其他元素<xmp><style>外部 XML 元素中的 CDATA 部分可能会出现类似的问题。

如果您需要真正忠实的转换,或者如果您的 HTML 混乱,您最好的选择可能是使用类似nu.validator的东西将 HTML 解析为 DOM ,然后使用How to pretty print XML from Java? 将 DOM 转换为有效的 XML。

即使您的输入是 XHTML,您也可能需要担心看起来像 CDATA 部分中的实体的字符序列。同样,解析和重新渲染可能是您的最佳选择。

于 2013-05-02T22:39:21.220 回答