【问题标题】:Nokogiri leaving HTML entities untouchedNokogiri 保持 HTML 实体不变
【发布时间】:2023-03-22 16:58:01
【问题描述】:

我希望 Nokogiri 保持 HTML 实体不变,但它似乎将实体转换为实际符号。例如:

 Nokogiri::HTML.fragment('<p>&reg;</p>').to_s

结果:"&lt;p&gt;®&lt;/p&gt;"

似乎没有任何东西可以将原始 HTML 返回给我。 .inner_html、.text、.content 方法都返回 '®' 而不是 '&amp;reg;'

Nokogiri 有没有办法让这些 HTML 实体保持不变?

我已经搜索了 stackoverflow 并找到了类似的问题,但没有一个与这个完全一样。

【问题讨论】:

  • 你见过this question吗?
  • 这个问题只涉及保持 UTF-8 不变,而不是避免实体的解码。
  • rdvdijk - 是的,我已经看到了这个问题,但这不是我要问的。作者在他的第一行代码中得到了正确的输出,但我没有。
  • 我会投票关闭这个作为 stackoverflow.com/questions/4476047/… 的副本,除了这个问题的公认答案是相当多的黑客而不是干净的“不要转换”。跨度>
  • 使用to_html :encoding =&gt; 'US-ASCII' 而不是to_s 输出&lt;p&gt;&amp;#174;&lt;/p&gt;,如果您的问题是试图避免编码问题,这可能很有用。据我所知,似乎没有办法让 Nokogiri 输出命名字符实体。

标签: ruby nokogiri


【解决方案1】:

不是一个理想的答案,但您可以通过设置允许的编码强制它生成实体(如果不是好名字):

#encoding: UTF-8
require 'nokogiri'
html = Nokogiri::HTML.fragment('<p>&reg;</p>')
puts html.to_html                              #=> <p>®</p>
puts html.to_html( encoding:'US-ASCII' )       #=> <p>&#174;</p>

如果 Nokogiri 在定义时使用“好”的实体名称,而不是总是使用简洁的十六进制实体,那就太好了,但即使这样也不会“保留”原始实体。

问题的根源在于,在 HTML 中,以下所有内容都描述了完全相同的内容:

<p>®</p>
<p>&reg;</p>
<p>&#xAE;</p>  
<p>&#174;</p>

如果您希望文本节点的 to_s 表示实际上是 &amp;reg;,那么描述它的标记实际上是:&lt;p&gt;&amp;amp;reg;&lt;/p&gt;

如果 Nokogiri 要始终为每个字符返回与输入文档时相同的编码,则需要将每个字符存储为记录实体引用的自定义节点。存在一个可能用于此的类 (Nokogiri::XML::EntityReference):

require 'nokogiri'
html = Nokogiri::HTML.fragment("<p>Foo</p>")
html.at('p') << Nokogiri::XML::EntityReference.new( html.document, 'reg' )
puts html
#=> <p>Foo&reg;</p>

但是,我找不到在使用 Nokogiri v1.4.4 或 v1.5.0 进行解析期间创建这些的方法。具体来说,在解析过程中Nokogiri::XML::ParseOptions::NOENT 的存在与否似乎不会导致创建一个:

require 'nokogiri'
html = "<p>Foo&reg;</p>"
[ Nokogiri::XML::ParseOptions::NOENT,
  Nokogiri::XML::ParseOptions::DEFAULT_HTML,
  Nokogiri::XML::ParseOptions::DEFAULT_XML,
  Nokogiri::XML::ParseOptions::STRICT
].each do |parse_option|
  p Nokogiri::HTML(html,nil,'utf-8',parse_option).at('//text()')
end
#=> #<Nokogiri::XML::Text:0x810cca48 "Foo\u00AE">
#=> #<Nokogiri::XML::Text:0x810cc624 "Foo\u00AE">
#=> #<Nokogiri::XML::Text:0x810cc228 "Foo\u00AE">
#=> #<Nokogiri::XML::Text:0x810cbe04 "Foo\u00AE">

【讨论】:

  • to_sto_(x)html 方法的输出也取决于您的默认编码。如果您仍有测试文件,请尝试将# encoding: UTF-8 添加到顶部并重新运行它们。我自己得到&lt;p&gt;®&lt;/p&gt;to_xhtmlto_(x)html 方法允许您显式设置所需的编码,看起来 Nokogiri 足够聪明,可以转义任何无法在输出编码中表示的字符。
  • 这行puts html.to_html( encoding:'US-ASCII' )拯救了我的一天
  • 仅供参考,这在 JRuby 中并不完全一样,因为它使用的库与 libxml 不同。
猜你喜欢
  • 2013-04-27
  • 1970-01-01
  • 2021-03-18
  • 1970-01-01
  • 2012-10-17
  • 2014-08-10
  • 2019-07-07
  • 1970-01-01
  • 2021-07-30
相关资源
最近更新 更多