【问题标题】:How can I render XML character entity references in Ruby?如何在 Ruby 中呈现 XML 字符实体引用?
【发布时间】:2011-03-13 14:58:17
【问题描述】:

我正在使用 Ruby 从 XML 网络服务中读取一些数据,如下所示:

<phrases>
  <phrase language="en_US">&iexcl;I&#39;m highly&nbsp;annoyed with character references!</phrase>
</phrases>

我正在解析 XML 并获取一组短语。如您所见,短语文本包含一些XML character entity references。我想用被引用的实际字符替换它们。这对于数字引用来说很简单,但对于 XML 和 HTML 引用就很麻烦了。我想避免在我的代码中包含每个 XML 或 HTML 字符引用的字符的大哈希,即http://www.java2s.com/Code/Java/XML/Resolvesanentityreferenceorcharacterreferencetoitsvalue.htm

肯定有这个库,对吧?

更新

是的,那里有一个图书馆,它叫HTMLEntities

: jmglov@laurana; sudo gem install htmlentities
Successfully installed htmlentities-4.2.4
: jmglov@laurana;  irb
irb(main):001:0> require 'htmlentities'
=> []
irb(main):002:0> HTMLEntities.new.decode "&iexcl;I&#39;m highly&nbsp;annoyed with character references!"
=> "¡I'm highly annoyed with character references!"

【问题讨论】:

  • &amp;gt;&amp;lt; 怎么样?如果替换 所有 实体,可能会破坏格式良好的 XML。
  • Matt,我正在处理的数据已经被 XML 解析过了;我在这里处理 CDATA,所以我希望解决所有实体。我将更新问题以明确这一点。
  • 那么您有一个数据本身包含实体的 XML 文档? (即您有 ASCII 字符串 &amp;nbsp; 的 XML 表示,而不是不间断空格的 XML 表示?)。
  • 应该指出&amp;nbsp; 不是原生的XML 实体。它出现在 XHTML 中是因为 XHTML 的 DTD 定义了它。
  • mu,感谢您提供How to encode/decode html entities in ruby 问题的链接。其中的解决方案让我大部分时间都受益;我仍然需要处理烦人的 ¡和  实体类,但这应该是可行的。

标签: ruby xml


【解决方案1】:

REXML 可以,虽然它不能处理 "¡"或“ ”。预定义的 XML 实体列表(除了 Unicode 数字实体)实际上非常小。见http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references

鉴于此输入 XML:

<phrases>
  <phrase language="en_US">&quot;I&#39;m highly annoyed with character references!&#x00a9;</phrase>
</phrases>

您可以像这样(例如)解析 XML 和嵌入的实体:

require 'rexml/document'

doc = REXML::Document.new(File.open('/tmp/foo.xml').readlines.join(''))
phrase = REXML::XPath.first(doc, '//phrases/phrase')
text = phrase.first # Type is REXML::Text
puts(text.value)

显然,该示例假定 XML 位于文件 /tmp/foo.xml 中。您可以很容易地传递一个 XML 字符串。在我的 Mac 和 Ubuntu 系统上,运行它会产生:

$ ruby /tmp/foo.rb
"I'm highly annoyed with character references!©

【讨论】:

    【解决方案2】:

    这不是提供解决方案的尝试,而是将我自己处理 XML 的一些经验与野外联系起来。我最初使用 Perl,后来使用 Ruby,如果您获取足够多的 XML 或 RDF/RSS/Atom 提要,您可以轻松体验这些体验。

    我经常看到 XML CDATA 包含编码和未编码的 HTML。编码的 HTML 可能是某人以正确的方式做事的结果,通过一些 API 或库来生成 XML。未编码的 HTML 可能是有人使用脚本将 HTML 与标签包装在一起,导致 XML 无效,但我还是不得不处理它。

    我还看到包含多次编码的 HTML 的 XML CDATA,要求我取消对所有内容的编码,即使在 XML 引擎完成它的工作之后也是如此。有时在中间传递过程中,由于有人附加了 cmets 或将来自不同字符集的多个 HTML 流连接在一起,我会突然在字符串中包含非 UTF8 字符以及编码字符。无论出于何种原因,它真的很丑陋,并导致 XML 解析中断或发出大量警告。我必须遍历内容,解码并检查前一个通道是否与当前解码通道相同,如果没有任何变化则放弃。不过,当时并不能保证我在有效字符集中有一个字符串,所以我必须告诉 iconv 将其转换为 UTF8 并丢弃无法完全转换的字符。

    Nokogiri 可以通过创造性地使用to_xmlto_html 方法以各种方式解码节点的内容。您还可以查看 HTMLEntities gem、Loofah 和其他以获取 CDATA 内容。 Loofah 很好,因为它旨在将您可能遇到的标签列入白名单/黑名单。

    XML 规范本应保护我们免受此类恶作剧的影响,但是,正如我的一位同事曾经告诉我的那样,“我们可以让它万无一失,但不能万无一失”。人们非常有创造力,这些规格对于那些懒得阅读或不在乎的人来说毫无意义。

    【讨论】:

    • 非常感谢指向HTMLEntities 的指针!我对您的答案进行了修改,以展示我是如何解决我的问题的,因此它应该会在审核时显示出来。
    • @Josh Glover,您不应该编辑我的答案。您应该编辑您的原始问题以显示您如何使用答案。
    猜你喜欢
    • 2018-08-20
    • 2016-12-10
    • 2010-11-22
    • 1970-01-01
    • 1970-01-01
    • 2011-12-20
    • 1970-01-01
    • 2011-03-22
    相关资源
    最近更新 更多