昨日の続き-XMLの読み出し
require 'pp' require 'kconv' require 'rexml/document' include REXML doc = REXML::Document.new File.open("newsing.xml","r") arr1 = [] doc.root.elements.each("//item") do |item| item.elements.each do |elem| arr2 = [] arr2 << elem.text.tosjis if elem.has_text? && elem.name != "comments" if elem.name == "comments" elem.elements.each(".//comment") do |comment| arr3 = [] comment.elements.each do |elem| arr3 << elem.text.tosjis if elem.has_text? end arr2 << arr3 end end arr1 << arr2 end end pp arr1 #=> [[url1,title2...,[comment1]],[url2,title2...[comment2]]...]
昨日と違うのは#elementsメソッドをつけてelementsクラスに変更→#eachメソッドを使えるようにして、XPATHで要素を取り出してるってことかな。多少分かりやすくなってるはず。
…まぁ長考した結果全然構成変わってないじゃん、とツッコミ受けそうだけど、細かくしすぎても後々分かりにくいので取りあえずこれをベースにすることにする。(これよりコード量を少なくしようとすると、XMLの方を変更しないといけないのかなぁ。)
参考
名前指定でコードを取り出すロジックも作ってみました。
require 'pp' require 'kconv' require 'rexml/document' include REXML doc = REXML::Document.new File.open("newsing.xml","r") arr1 = [] doc.root.each_element do |elem| arr2 = [] arr2 << elem.elements["url"].text arr2 << elem.elements["title"].text arr2 << elem.elements["main_text"].text arr2 << elem.elements["picker"].text arr2 << elem.elements["picktime"].text arr2 << elem.elements["picktime"].text arr2 << elem.elements["pick_com"].text arr2 << elem.elements["picker_eval"].text arr2 << elem.elements["pt"].text if elem.elements["comments"] elem.elements["comments"].each_element do |elem| arr3 = [] arr3 << elem.elements["commenter"].text arr3 << elem.elements["comtime"].text arr3 << elem.elements["com_eval"].text arr3 << elem.elements["com_text"].text arr3 << elem.elements["nicecomment"].text arr2 << arr3 end end arr1 << arr2 end pp arr1
いちいち "if elem.has_text?" って書くのが面倒になって挫折したけど、こっちの方が分かりやすいかもしれない。
# 配列の出力はppで出すのがお勧めです。
ちょっくらXPathの勉強
リファレンスとかあまり読まない僕ですが(←だめじゃん)、「対象ノードのコメント一覧を抽出する方法」を調べるためにがんばって読んでみた。
データベース連携からシステム統合まで、企業システムの「つなぐ」を実現|インフォテリア株式会社
これによると、
elem.elements.each("//comment") # rootノード以下の全てのcommentという子孫エレメント elem.elements.each(".//comment") # コンテキスト(カレント)ノード以下の全てのcommentという子孫エレメント
らしいです。REXMLの使い方だけじゃなくXPathの知識と合わせて使わないといけないんだね><