読者です 読者をやめる 読者になる 読者になる

【Ruby】【nokogiri】cssでのタグ指定

nokogiriを利用して、xmlのパースをしようと思ったのですが、思っていた動きと違う動きがあったのでメモです。

普段、

doc = Nokogiri::HTML(xml本体,nil,"utf-8")
doc.css("user").each do |xml_user|
  何か処理
end

というような感じで、使っていました。
その時に、css("名前")というようにして、タグ名を指定していました。

ここで今回の話です。
例えば、以下のようなxmlがあったとき、

<id>
  1
</id>
<status>
  <id>
    20
  </id>
</status>
doc.css("id")

とすると、一番親に当たるidしか取れず、statusのidはまたもう一段階指定が要るのだと思っていました。
しかし、両方取れていました。
以下irbでの実行結果です。

>> require 'nokogiri'
=> []
>> test = Nokogiri::HTML("<id>10</id><status><id>20</id></status>",nil,"utf-8")
=> #<Nokogiri::HTML::Document:0x1d2ccfa name="document" children=[#<Nokogiri::XM
L::DTD:0x1d2c408 name="html">, #<Nokogiri::XML::Element:0x1d2c26e name="html" ch
ildren=[#<Nokogiri::XML::Element:0x1d286aa name="body" children=[#<Nokogiri::XML
::Element:0x1d2804c name="id" children=[#<Nokogiri::XML::Text:0x1d27bba "10">]>,
 #<Nokogiri::XML::Element:0x1d272a0 name="status" children=[#<Nokogiri::XML::Ele
ment:0x1d26f30 name="id" children=[#<Nokogiri::XML::Text:0x1d26c1a "20">]>]>]>]>
]>




>> test.css("id")
=> [#<Nokogiri::XML::Element:0x1d2804c name="id" children=[#<Nokogiri::XML::Text
:0x1d27bba "10">]>, #<Nokogiri::XML::Element:0x1d26f30 name="id" children=[#<Nok
ogiri::XML::Text:0x1d26c1a "20">]>]

↑見にくいですが2つとも取れています。
配列で渡されているので、

>> id_test = test.css("id")
=> [#<Nokogiri::XML::Element:0x1d2804c name="id" children=[#<Nokogiri::XML::Text
:0x1d27bba "10">]>, #<Nokogiri::XML::Element:0x1d26f30 name="id" children=[#<Nok
ogiri::XML::Text:0x1d26c1a "20">]>]
>> id_test[0]
=> #<Nokogiri::XML::Element:0x1d2804c name="id" children=[#<Nokogiri::XML::Text:
0x1d27bba "10">]>

適当な変数に代入後、hoge[0]などと指定して取りました。
わすれないように…

ちなみに、[0]などと指定しないままでいると、配列の中身がくっついた状態になっていました…。
具体例:
hoge[0]="12"
hoge[1]="10"
のときにhoge="1210"

しばらく気付いてなかったため、プログラムが変な挙動を起こし続けていました…。