問題は、HTML が無効であることです。これを使用してテストしました:
require 'nokogiri'
doc = Nokogiri::HTML::DocumentFragment.parse(<<EOT)
<p>some paragraph</p>
<a href="https://url...com"><span style="color: #a5a5a5;"><i>qwerty</i></span> ytrewq </a>
<code>
<html>
<p>
qwerty
</p>
</html>
</code>
<p>some other paragraph</p>
<a href="https://url...com"><span style="color: #a5a5a5;"><i>qwerty</i></span> ytrewq </a>
EOT
puts doc.errors
ドキュメントを解析した後、Nokogiri はerrors
解析中に見つかったエラーのリストを配列に入力します。HTML の場合、doc.errors
以下が含まれます。
htmlParseStartTag: misplaced <html> tag
その理由は、<code>
ブロック内でタグが HTML エンコードされていないためです。
HTML エンティティを使用して次のように変換します。
<html>
<p>
qwerty
</p>
</html>
そして、それはうまくいきます。
Nokogiri は XML/HTML パーサーであり、マークアップのエラーを修正して、プログラマーがドキュメントを使用できるようにします。この場合、<html>
ブロックが間違った場所にあるため、タグが削除されます。Nokogiri は、タグがエンコードされていても気にしません。その時点では、タグは単なるテキストであり、タグではないからです。
編集:
gsubで事前解析して、コードブロックでhtmlを変換してみます
require 'nokogiri'
html = <<EOT
<p>some paragraph</p>
<a href="https://url...com"><span style="color: #a5a5a5;"><i>qwerty</i></span> ytrewq </a>
<code>
<html>
<p>
qwerty
</p>
</html>
</code>
<p>some other paragraph</p>
<a href="https://url...com"><span style="color: #a5a5a5;"><i>qwerty</i></span> ytrewq </a>
EOT
doc = Nokogiri::HTML::DocumentFragment.parse(html.gsub(%r[<(/?)html>], '<\1html>'))
puts doc.to_html
どの出力:
<p>some paragraph</p>
<a href="https://url...com"><span style="color: #a5a5a5;"><i>qwerty</i></span> ytrewq </a>
<code>
<html>
<p>
qwerty
</p>
</html>
</code>
<p>some other paragraph</p>
<a href="https://url...com"><span style="color: #a5a5a5;"><i>qwerty</i></span> ytrewq </a>
編集:
これにより<html>
、解析前にタグが処理されるため、Nokogiri は<code>
ブロックを無傷でロードできます。次に、ブロックを見つけ、<code>
エンコードされた<html>
開始タグと終了タグをアンエスケープし、結果のテキストをコンテンツとしてブロックに挿入し<code>
ます。コンテンツとして挿入されるため、Nokogiri が DOM を HTML としてレンダリングすると、テキストは必要に応じてエンティティとして再エンコードされます。
require 'cgi'
require 'nokogiri'
html = <<EOT
<p>some paragraph</p>
<a href="https://url...com"><span style="color: #a5a5a5;"><i>qwerty</i></span> ytrewq </a>
<code>
<html>
<p>
qwerty
</p>
</html>
</code>
<p>some other paragraph</p>
<a href="https://url...com"><span style="color: #a5a5a5;"><i>qwerty</i></span> ytrewq </a>
EOT
doc = Nokogiri::HTML::DocumentFragment.parse(html.gsub(%r[<(/?)html>], '<\1html>'))
code = doc.at('code')
code.content = CGI::unescapeHTML(code.inner_html)
puts doc.to_html
どの出力:
<p>some paragraph</p>
<a href="https://url...com"><span style="color: #a5a5a5;"><i>qwerty</i></span> ytrewq </a>
<code>
<html>
<p>
qwerty
</p>
</html>
</code>
<p>some other paragraph</p>
<a href="https://url...com"><span style="color: #a5a5a5;"><i>qwerty</i></span> ytrewq </a>