2013-05-02 84 views
1

这是输入:如何隐藏HTML实体但保持XML实体不变?

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

这是一个有效的HTML,但不是有效的XML(因为&euro;没有在DTD中声明)。一个有效的XML看起来像:

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

你能推荐一些Java库,可以帮我取消转义HTML实体,并将其转换为XML实体?

+0

你想这样做到一个完整的文件,或只是实体文本?你是否想用XML读取HTML文件? (如果是这样,那么不仅仅是实体需要担心) – 2013-05-02 21:24:53

回答

0

Apache commons StringUtils.unescapeHTML会做。一般而言,XML API自身会转义XML实体。因此,您使用&设置了DOM属性或内容文本,并生成了&amp;。 您可以将字符保留为UTF-8;不需要制作它们的数字实体。

当然你也可以处理HTML DTD。这也会填充字符。这可能需要几十秒。不幸的是,有很多实体,DTD包含和缓慢的服务器,所以最好使用这些DTD创建本地XML目录或缓存实体处理程序。

import org.apache.commons.lang.StringEscapeUtils; 

    String html = "<div>The price is &lt; 5 &euro;</div>"; 
    String text = StringEscapeUtils.unescapeHtml(html); 
    System.out.println("Text: " + text); 

输出以UTF-8的Linux:

Text: <div>The price is < 5 €</div> 

这表明属性值和内部文本应处理片明智的。

+0

您能给出一个实用的Java示例,它可以处理我的文本(参见上文)吗? – yegor256 2013-05-03 17:30:43

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部分中的实体的字符序列。再次,解析和重新渲染可能是您的最佳选择。