データ抽出処理 ++
前に作った Extract クラスに一工夫を加えてみた。
素直に Scraper::Base を使えって言われるとそうかもしれないけれど。
つい、こんな仕組みで動いているんだ、と気づくとそれに近いものを
作って試してみたくなるんだよね。ただ、利用目的に合わなければ、
「使わない」という選択もあり、だと思う。
でも、Ruby にはメソッドを上書きしてしまうこともできるし。。。
その点を考えると、よくできてるな、Ruby。
ソースコード
require 'rubygems' require 'hpricot' require 'extract' require 'pp' text =<<EOD <root> <title>extract test</title> <record> <item> <name>user01</name> <id>0</id> <date>2007/11/25</date> <comment>comment01 foobar</comment> </item> <item> <name>user02</name> <id>1</id> <date>2007/11/28</date> <comment>comment02 foobar</comment> </item> <item> <name>user03</name> <id>2</id> <date>2007/11/30</date> <comment>comment03 foobar</comment> </item> </record> </root> EOD class ExtractBase @@instances = {} class << self attr_accessor :instances end def parse(text) define = @@instances[self.class] Extract.match :text => text do record(define[:options], &define[:block]) end end def self.process(opt, &block) @@instances[self] = {:options => opt, :block => block} end end class Foo < ExtractBase process :regexp => '<item>(.+?)</item>' do item :name => { :regexp => '<name>(.+?)</name>' } item :id => { :regexp => '<id>(.+?)</id>' } item :date => { :regexp => '<date>(.+?)</date>' } item :comment => { :regexp => '<comment>(.+?)</comment>' } end end foo = Foo.new pp foo.parse(text) # => # {:item=> # [{:date=>"2007/11/25", # :comment=>"comment01 foobar", # :name=>"user01", # :id=>"0"}, # {:date=>"2007/11/28", # :comment=>"comment02 foobar", # :name=>"user02", # :id=>"1"}, # {:date=>"2007/11/30", # :comment=>"comment03 foobar", # :name=>"user03", # :id=>"2"}], # :summary=>{}}