XML処理 REXMLの使い方
よく忘れるので。
こんなXMLを用意した場合の例。
<root> <a name="a1"> <b>bbb1</b> <b>bbb2</b> <b>bbb3</b> <c>ccc1</c> </a> <a> <b>bbb4</b> <b>bbb5</b> </a> <a name="a3" price="100"></a> </root>
必ずrequire
require 'rexml/document'
XML読み込み
doc = REXML::Document.new(open("hoge.xml"))
とりあえず全文dump
puts doc #結果 <root> <a name='a1'> <b>bbb1</b> <b>bbb2</b> <b>bbb3</b> <c>ccc1</c> </a> <a> <b>bbb4</b> <b>bbb5</b> </a> <a name='a3' price='100'/> </root>
ピンポイントで取得(1番目Aタグの子、1番目Bタグの値)
添え字を指定していないので1番目のものが取られる
puts doc.elements['root/a/b'].text #結果 bbb1
添え字を指定した場合
puts doc.elements['root/a[2]/b[2]'].text #結果 bbb5
全Aタグの全子要素bタグ値を全部表示
doc.elements.each('root/a/b') do |element| puts element.text end #結果 bbb1 bbb2 bbb3 bbb4 bbb5
これは「全Aタグの、それぞれ1つ目のBタグ」となる。
ループするのはAタグで、Bはループしていない。
そして、3つ目Aは子要素にBタグがないのでエラーになる。
doc.elements.each('root/a') do |element| puts element.elements['b'].text end
1つ目Aタグのbタグ値全部表示
doc.elements.each('root/a[1]/b') do |element| puts element.text end #結果 bbb1 bbb2 bbb3
1つ前のタグと後ろのタグ
doc.elements.each('root/a[1]/b[2]') do |element| puts element.previous_element.text end #結果 bbb1 doc.elements.each('root/a[1]/b[2]') do |element| puts element.next_element.text end #結果 bbb3
タグ名取得
doc.elements.each('root/a[1]') do |element| puts element.name end #結果 a
タグ名取得(子要素)
doc.elements.each('root/a[1]') do |element| puts element.elements[4].name end #結果 c
子要素数表示
doc.elements.each('root/a[2]') do |element| puts element.elements.size end #結果 2
属性値取得
doc.elements.each('root/a[3]') do |element| puts element.attributes["name"] end #結果 a3
属性はHashで返る
hash = Hash.new doc.elements.each('root/a[3]') do |element| hash = element.attributes end puts hash.size #=>2 puts hash["name"] #=>a3
属性が特定値の要素を持つタグの子要素値
doc.elements.each("root/a[@name='a1']/b") do |element| puts element.text end #結果 bbb1 bbb2 bbb3 #"root/[@name='a1']/b" という指定も可能。この場合はタグ名を限定しなくなる
特定の属性値を持つタグの、別の属性値
puts doc.elements["root/a[@name='a3']"].attributes['price'] #結果 100
参考