4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Nokogiri 1.5.6で、属性アクセサーが大きく変わった

Last updated at Posted at 2013-01-01

先日、Nokogiriの1.5.6がリリースされました。
このアップデートで属性アクセサーに変更があって、GitHubでもイシューが上がっています。その中でメンテナーの@flaverjonesも認めているように、これは1.5.5→1.5.6というパッチレベルリリースには相応しくないほど大きな変更です。

というか、実際僕もハマりました(余談ですがTravisがテストのこけたのを教えてくれて気付きました、改めて素晴らしいサービスだと思いました)。

ここで属性アクセサーと言っているのは、

<input type="email">

というメールアドレスフィールドがあった時に

input['type'] # => "email"

という風にアクセスして値を取れるNokogiri::XML::Node#[]メソッドのことです。

では、どのように変化したのでしょうか、ちょっとプログラムを書いてみました。

nokogiri-attribute.rb
version = ARGV.shift
gem 'nokogiri', version
require 'nokogiri'
puts Nokogiri::VERSION
doc = Nokogiri.XML(DATA.read)
nav = (doc/'nav').first
p [nav['type'], nav['epub:type']]

__END__
<?xml version="1.0"?>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:epub="http://www.idpf.org/2007/ops">
  <head>
    <title>Table of Contents for Example Book</title>
  </head>
  <body>
    <nav epub:type="toc">
    </nav>
  </body>
</html>
$ ruby noogiri-attribute.rb 1.5.5
1.5.5
["toc", nil]
$ ruby noogiri-attribute.rb 1.5.6
1.5.6
[nil, "toc"]

今まで取れていた値が取るのに、名前空間プリフィクスが必要になってしまっています。

当然、epub:typeなんて、任意の名前空間プリフィクスを使ったキーは使いたくない(環境を限定できればその限りではない)。
ではどうすればいいのか? というと、書き捨てのスクリプトはともかく、ある程度長く使うことが分かっているものは、#[]の代わりに#attribute_with_nsを使うのがいいかなあと思っています。

ns_uri = 'http://www.idpf.org/2007/ops'
nav = (doc/'nav').first
attr = nav.attribute_with_ns('type', ns_uri)
type = attr.nil? ? nil : attr.value # attr.to_sでいいことも多いけど、nilと空文字列""を区別したいこともある
p type # => 1.5.5でも1.5.6でも"toc"

他にいいメソッド見付けたら教えてください!

ま、XML名前空間を使った属性アクセスなんて、している人殆どいないでしょうけど……。

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?