QA@IT
«回答へ戻る

回答を投稿

Nokogiri::HTML::fragmentを使うのはどうでしょうか?

例題ですがNokogiri::HTMLではなくNokogiri::XMLを使うと文字化けせずに出力してくれます。
たぶんNokogiri::HTMLがparseする時になにか問題が起きるようです。Nokogiri::HTML::fragmentはparseせずに文字列をそのまま渡してくれるので大丈夫なようです。

# -*- coding: UTF-8 -*-
require 'nokogiri'
html = <<EOF
<p>
  hello
</p>
<p>
  ストーリー
</p>
EOF
doc = Nokogiri::HTML(html, nil, 'utf-8')


doc.css('p').each do |d|
  p d.inner_html
  d.inner_html = 'new'
  p d.inner_html
  p d.inner_html =  Nokogiri::HTML::fragment('ニュー')
  p d.inner_html
end

puts doc

出力結果

[Documents]$ ruby unicode_mojibake.rb 
"\n  hello\n"
"new"
#<Nokogiri::HTML::DocumentFragment:0x3fcb8a0ef958 name="#document-fragment">
"ニュー"
"\n  ストーリー\n"
"new"
#<Nokogiri::HTML::DocumentFragment:0x3fcb8a0ed888 name="#document-fragment">
"ニュー"
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body>
<p>ニュー</p>
<p>ニュー</p>
</body></html>

Nokogiri::HTML::fragmentを使うのはどうでしょうか?

例題ですがNokogiri::HTMLではなくNokogiri::XMLを使うと文字化けせずに出力してくれます。
たぶんNokogiri::HTMLがparseする時になにか問題が起きるようです。[Nokogiri::HTML::fragment](http://nokogiri.org/Nokogiri/HTML.html)はparseせずに文字列をそのまま渡してくれるので大丈夫なようです。


~~~ruby
# -*- coding: UTF-8 -*-
require 'nokogiri'
html = <<EOF
<p>
  hello
</p>
<p>
  ストーリー
</p>
EOF
doc = Nokogiri::HTML(html, nil, 'utf-8')


doc.css('p').each do |d|
  p d.inner_html
  d.inner_html = 'new'
  p d.inner_html
  p d.inner_html =  Nokogiri::HTML::fragment('ニュー')
  p d.inner_html
end

puts doc

~~~

出力結果

~~~ruby
[Documents]$ ruby unicode_mojibake.rb 
"\n  hello\n"
"new"
#<Nokogiri::HTML::DocumentFragment:0x3fcb8a0ef958 name="#document-fragment">
"ニュー"
"\n  ストーリー\n"
"new"
#<Nokogiri::HTML::DocumentFragment:0x3fcb8a0ed888 name="#document-fragment">
"ニュー"
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body>
<p>ニュー</p>
<p>ニュー</p>
</body></html>

~~~