Nokogiri保持HTML实体不变

Ric*_*ard 16 ruby nokogiri

我希望Nokogiri保持HTML实体不受影响,但似乎是将实体转换为实际符号.例如:

 Nokogiri::HTML.fragment('<p>&reg;</p>').to_s
Run Code Online (Sandbox Code Playgroud)

结果是: "<p>®</p>"

似乎没有什么能将原始HTML返回给我..inner_html,.text,.content方法都返回'®'而不是'&reg;'

Nokogiri有没有办法让这些HTML实体不受影响?

我已经搜索了stackoverflow并发现了类似的问题,但没有完全像这个问题.

谢谢.

Phr*_*ogz 18

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

#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>
Run Code Online (Sandbox Code Playgroud)

如果Nokogiri使用定义的实体的"漂亮"名称,而不是总是使用简洁的十六进制实体,那将是很好的,但即使这样也不会"保留"原始实体.

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

<p>®</p>
<p>&reg;</p>
<p>&#xAE;</p>  
<p>&#174;</p>
Run Code Online (Sandbox Code Playgroud)

如果你想要实际to_s表示文本节点,&reg;那么描述它的标记实际上是:<p>&amp;reg;</p>.

如果Nokogiri总是返回与用于输入文档的每个字符相同的编码,则需要将每个字符存储为记录实体引用的自定义节点.存在一个可能用于this(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>
Run Code Online (Sandbox Code Playgroud)

但是,我无法找到一种方法来在使用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">
Run Code Online (Sandbox Code Playgroud)