NokogiriはRubyでHTML/XMLを解析するためのライブラリです。
Railsアプリケーションの場合、自分で使っていなくて、使用しているGemのどれかが依存している場合があり、自動的にインストールする羽目になったという方も多いかもしれません。
NokogiriはWebドキュメントを解析し、特定の要素を検索したり抽出したりする場合に使用できますが、閉じタグが省略されているなど不正なHTMLを読みこみ、正しい形に変換して出力することもできるようです。
これは例えば次のように実行します(参考: Fix invalid html using Nokogiri)。
doc = Nokogiri::HTML.parse(<<-eohtml)
<html>
<head>
<title>Hello World</title>
<body>
<h1>This is an awesome document</h1>
<p>
I am a paragraph
<a href="http://google.ca">I am a link</a>
<table><tr><td>table content!
</body>
eohtml
valid_html = doc.to_s
puts valid_html
実行すると、tableタグやhtmlタグなど、省略されていた閉じタグが追加されたHTMLが出力されます。
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Hello World</title>
</head>
<body>
<h1>This is an awesome document</h1>
<p>
I am a paragraph
<a href="http://google.ca">I am a link</a>
</p>
<table><tr><td>table content!
</td></tr></table>
</body>
</html>
この機能を利用してHTMLを切り詰めることもできます。
HTMLを切り詰めることもできる
以下のプログラムはRailsアプリケーションを想定しています。truncateで文字列を短くしたあと、Nokogiri::HTML.parseを呼び出しています。
html=<<eohtml
<html>
<head>
<title>ハーローワールド</title>
<body>
<h1>テスト用ドキュメントです</h1>
<ul>
<li>aaaaaaaaaaaaaaaaaaaa</li>
<li>bbbbbbbbbbbbbbbbbbbb</li>
<li>cccccccccccccccccccc</li>
<li>dddddddddddddddddddd</li>
<table>
<tr><td>table content 1!</td>
<tr><td>table content 2
</body>
eohtml
str = html.truncate(220, omission: '')
doc2 = Nokogiri::HTML.parse(str)
puts doc2.to_s
puts doc2.to_s.length
実行結果です。
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>ハーローワールド</title>
</head>
<body>
<h1>テスト用ドキュメントです</h1>
<ul>
<li>aaaaaaaaaaaaaaaaaaaa</li>
<li>bbbbbbbbbbbbbbbbbbbb</li>
<li>cccccccccccccccccccc</li>
<li>dddddddddddddd</li>
</ul>
</body>
</html>
431
元々のHTMLは短くなっていることがわかります。ただし、DOCTYPEやmetaタグ、閉じタグが追加されたせいで、全体の文字数は431文字まで増えています。最終的な結果を指定文字数までに抑えたい場合、さらに処理が必要となります。