我希望Nokogiri将HTML实体保持原样,但似乎将实体转换为实际符号.例如:
Nokogiri::HTML.fragment('<p>®</p>').to_s
结果为:“< p>®< / p>”
没有什么似乎返回原来的HTML回到我.
.inner_html,.text,.content方法都返回’®’而不是’& reg’
有没有办法让诺基里离开这些HTML实体?
我已经搜索到stackoverflow,并发现类似的问题,但没有完全像这样.
谢谢.
解决方法
不是一个理想的答案,但您可以强制它通过设置允许的编码来生成实体(如果不是很好的名称):
#encoding: UTF-8 require 'nokogiri' html = Nokogiri::HTML.fragment('<p>®</p>') puts html.to_html #=> <p>®</p> puts html.to_html( encoding:'US-ASCII' ) #=> <p>®</p>
如果Nokogiri使用定义的实体的“漂亮”名称,而不是总是使用简洁的十六进制实体,那么这将是很好的,但即使这样不会保留原始的实体.
问题的根源在于,在HTML中,以下内容都描述了完全相同的内容:
<p>®</p> <p>®</p> <p>®</p> <p>®</p>
如果你想要一个文本节点的to_s表示实际上是® reg;那么描述的标记将是:< p>& amp; reg;< / p> ;. 如果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®</p>
但是,在使用Nokogiri v1.4.4或v1.5.0进行解析时,我找不到一种方法来创建它们.具体来说,解析期间Nokogiri::XML::ParseOptions::NOENT
的存在或不存在似乎不会导致创建一个:
require 'nokogiri' html = "<p>Foo®</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">