HTMLにエラーがあるとブラウザや支援技術が適切にHTMLを処理できない可能性があり、さまざまな問題が発生する場合があります。WCAG 2.0の達成基準 4.1.1を満たしている事を確認するためにも、ウェブページをバリデートすることは重要な作業の一つと考えています。
バリデーターにはThe W3C Markup Validation Serviceがありますが、未公開のコンテンツを外部に送信することは避けたい場合もあるかと思います。そのような場合は、The Nu Html Checker (v.Nu)からvnu.jar
ファイルなどをダウンロードし、ローカルマシンで気軽にバリデートすることができます。
単一のページをバリデートする
Githubのvalidator/validatorからvnu.jar
をダウンロードします。適当なディレクトリに置いてjava -cp vnu.jar nu.validator.servlet.Main 8888
を実行し、 http://localhost:8888/
にアクセスすると、おなじみの Nu Html Checker が表示されます。
ちなみに、私のマシンはjava
を実行すると古いバージョンが実行されるため、"/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java"
を実行するようにしています。
複数のページをまとめてバリデートする
Nu Html Checkerを利用して複数のページをまとめてバリデートする方法を探したところ、以前から利用しているSite Validatorのサイトで「W3C Validator is legacy, long live Validator.nu」の記事を見つけ、「 nunchaku 」というクライアントがあることを知りました。そこでRubyを用いて、sitemap.xml
に記載されているURLをまとめてバリデートするコードを書きました。
ソースコード
require "nunchaku"
require "rexml/document"
require "json"
require "color_echo"
doc = REXML::Document.new(open("sitemap.xml"))
doc.elements.each("urlset/url/loc") do |element|
loc = element.text
# https://github.com/sitevalidator/nunchaku
checker = Nunchaku.check(loc, { checker_uri: "http://localhost:8888" })
error = 0
warning = 0
info = 0
checker = Nunchaku.check(loc)
checker.raw["messages"].each{|message|
message.each{|key, value|
if key == "type" then
case value
when "error"
error += 1
when "info"
info += 1
end
elsif key == "subType"
if value == "warning" then
warning += 1
info -= 1
end
end
}
}
if error > 0 then
CE.pickup([/Error: [\d]+/], :red)
end
if warning > 0 then
CE.pickup([/Warning: [\d]+/], :yellow)
end
if error == 0 && warning == 0 then
CE.reset
end
puts loc
puts "└ Error: #{error}, Warning: #{warning}, Info: #{info}"
puts "\n"
end
実行方法と実行結果
先に紹介したコードをnunchaku.rb
などで保存します。また、grunt-simple-xmlsitemapやgulp-sitemapを利用して、バリデート対象のURLを記載したsitemap.xml
を用意します。
ターミナルでruby nunchaku.rb
を実行すると、以下のようにバリデート対象URLとError, Warning, Infoの数が出力されます。
補足
nunchakuのオプションでローカルマシンのNu Html Cheker URIを指定しても上手く反映されませんでした。ひとまずgems/nunchaku-0.2.1/lib/nunchaku/checker.rb
のchecker_uri
を変更しました。