REXML で SAX風に id と class を抜き出してみた
こんな風に使います。
ruby class_id_picker.rb FILENAME
当然、HTML は処理できなくて、XHTML でないとダメです。
使い道は、とりあえず付けてある名前を推敲するのに使えるかなーくらい。あとは id が unique かどうかとか? 普通はこんなの要らない気がする。
attrs をチェックする際にわざわざ
//i
で引っ掛けているのは REXML でのパース時に大文字や小文字への正規化は行われないためです。
#! /usr/bin/env ruby
require 'rexml/document'
require 'rexml/streamlistener'
class ClassIdPicker
def initialize
@ids = []
@classes = []
end
attr_reader( :ids, :classes )
def self.parse( io )
obj = self.new
REXML::Document.parse_stream( io, Listener.new( obj.ids, obj.classes ) )
return obj
end
def attrs
return instance_variables.map { |e|
e.sub( /\A@/, '' )
}
end
def browse
puts "=== Classes ==="
puts @classes.sort.uniq.join( "\n" )
puts "=== Ids ==="
puts @ids.sort.uniq.join( "\n" )
end
class Listener
include REXML::StreamListener
def initialize( ids, classes )
@ids = ids
@classes = classes
end
attr_reader( :ids, :classes )
def tag_start( name, attrs )
attrs.each_pair { |name, val|
case name
when /\Aid\z/i
@ids.push( val )
when /\Aclass\z/i
@classes.push( val )
end
}
end
end
end
if ( __FILE__ == $0 )
app = ClassIdPicker.parse( ARGF.file )
# 数を数えながら表示してみる
app.attrs.each { |attr|
p attr
attr_list = app.send( attr ).dup
attr_list.sort.uniq.each { |name|
puts "#{name}\t#{attr_list.grep( name ).size}"
}
}
end