Ответ 1
Не идеальный ответ, но вы можете заставить его сгенерировать сущности (если не красивые имена), установив разрешенную кодировку:
#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>
Было бы неплохо, если Нокогири использовал "хорошие" имена сущностей, которые были определены, вместо того, чтобы всегда использовать краткую шестнадцатеричную сущность, но даже это не было бы "сохранение" оригинала.
Корень проблемы состоит в том, что в HTML следующие описания описывают одно и то же содержимое:
<p>®</p>
<p>®</p>
<p>®</p>
<p>®</p>
Если вы хотите, чтобы представление to_s
текста node было фактически ®
, тогда разметка, описывающая это, действительно была бы: <p>&reg;</p>
.
Если Nokogiri должен всегда возвращать одну и ту же кодировку для каждого символа, которая использовалась для ввода документа, ему нужно было бы сохранить каждый символ в качестве пользовательской node записи ссылки на сущность. Существует класс, который может быть использован для этого (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">