listrecv / gmail.com wrote: > Thanks. > > But I'd like to just extract the attribute value via Xpath. > > If my Xpath is correct, I could just do '//customer/phone/@type' to get > 'home'. Is there any way I can do this in Ruby? p DATA.read.xchain('customer/@loc="south"/phone').first.atr['type'] __END__ <customer loc="north"> <phone type='home'>0115</phone> <phone type='mobi'>07807</phone> </customer> <customer loc="south"> <phone type='home'>0319</phone> </customer> The rest: class Array; alias atr first; alias txt last end class String def xtag(s) result = [] scan( %r! < #{s} (?: \s+ ( [^>]* ) )? / > | < #{s} (?: \s+ ( [^>]* ) )? > ( .*? ) </ #{s} > !mx ) \ { |unpaired, attr, data| h = { } attr = ( unpaired || attr ) attr.scan( %r{ ( \S+ ) = ( ["'] ) ( .*? ) \2 }x ){ |k,q,v| h[k] = v } if attr block_given? ? ( yield [ h, data ] ) : result << [ h, data ] } result end def xchain(s) s.scan(%r! [^/"]+ (?: "[^"]*" )? !x).inject([[nil,self]]){|ary,str| if "@" == str[0,1] str =~ /@(.*?)="(.*)"/ ary.select{|a,t| a[$1] == $2 } else return [] if [] == ary ary[0].txt.xtag(str) end } end end