这是输入:
<div>The price is < 5 €</div>
它是有效的 HTML,但不是有效的 XML(因为€
未在 DTD 中声明)。有效的 XML 如下所示:
<div>The price is < 5 €</div>
你能推荐一些 Java 库来帮助我对 HTML 实体进行转义并将它们转换为 XML 实体吗?
使用 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. " & ä
* @return XML String, HTML4 Entities replaced, but XML Entites remain (e.g. " und &)
*/
public static final String unescapeHtmlToXml(final String input) {
return UNESCAPE_HTML_SPECIFIC.translate(input);
}
}
所有 HTML 命名字符引用的列表可在http://www.whatwg.org/specs/web-apps/current-work/multipage/entities.json获得
如果您可以容忍偶尔出现的错误,您可以检查该文件并将独立 XML 中不允许的所有命名字符引用替换为相应的数字字符引用。
如果您的输入是 HTML,而不是 XHTML,那么这种简单的方法可能会遇到问题:
<script>var y=1, lt = 3, x = y< alert(x);</script>
包含一个脚本元素,其内容未使用实体进行编码,因此天真地替换<
此处将破坏脚本。还有其他元素<xmp>
和<style>
外部 XML 元素中的 CDATA 部分可能会出现类似的问题。
如果您需要真正忠实的转换,或者如果您的 HTML 混乱,您最好的选择可能是使用类似nu.validator的东西将 HTML 解析为 DOM ,然后使用How to pretty print XML from Java? 将 DOM 转换为有效的 XML。
即使您的输入是 XHTML,您也可能需要担心看起来像 CDATA 部分中的实体的字符序列。同样,解析和重新渲染可能是您的最佳选择。