xgrep.rb
30分シリーズ、その14。XML用grep、xgrep.rb。
TypingManiaの歌詞ダウンロードに使おうと思ったら、XMLがvalidじゃなかったので使えなかった可哀想な子。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <musicinformation> <musicinfo id="0" xmlpath="XML/Memorability.xml" musicpath="mp3/Memorability.mp3"> <musicname>Memorability</musicname> <artist>緋火流</artist> <genre>Pop</genre> <level>04</level> </musicinfo> </musicinformation>
というのがXMLがあったとする。
すると、
$ xgrep musicinformation/musicinfo musiclist.xml musiclist.xml: <musicinfo id="0" xmlpath="XML/Memorability.xml" musicpath="mp3/Memorability.mp3"> <musicname>Memorability</musicname> <artist>緋火流</artist> <genre>Pop</genre> <level>04</level> </musicinfo> $ xgrep musicname/text() musiclist.xml musiclist.xml: Memorability $ xgrep musicinfo/@id() musiclist.xml musiclist.xml: 1
となります。
#!/opt/local/bin/ruby -w require 'REXML/Document' def xgrep(io,xpath,cmd,filename='<->',&print) include REXML doc = Document.new io doc.root.each_element(xpath){|elem| x = case cmd when /\Atext/ elem.text when /\A@(\w+)/ elem.attributes[$1] else elem end print.call "%s:\t%s" % [filename,x] } end if ARGV[0] =~ %r!(.*)/([^/]+)\(\)! xpath = $1 cmd = $2 else xpath = ARGV[0] cmd = 'raw' end ARGV.shift if ARGV.empty? then xgrep(STDIN,xpath,cmd,&method(:puts)) else ARGV.each do|filename| File.open(filename) do |io| xgrep(io,xpath,cmd,filename,&method(:puts)) end end end