class CompactHandler include REXML::SAX2Listener def initialize @closed=false @indent=0; @entities = {"&"=>"&", """=>'"', "'"=>"'", "<" => "<", ">" => ">"} end def start_element(uri,localname,qname,attributes) if @closed print "\n"+" "*@indent @closed=false end @indent += 1+localname.length() print localname+"[" first=true; attributes.each do |key,value| print "\n"+" "*@indent if !first first=false print "@#{key}[#{expandEntities(value)}]" @closed=true end end def end_element(uri,localname,qname) print "]" @closed=true @indent=@indent-1-localname.length end def characters(text) if text.strip.length>0 if @closed print "\n"+" "*@indent @closed=false end text.strip! # remove leading and trailing space text.gsub!(/[\s\r\n]+/,' ') # normalize space print expandEntities(text) @closed=true end end def entitydecl(name,decl) @entities["&"+name+";"]=decl end def expandEntities(text) if text.include?("&") # match entities as long as there are replacements @entities.each{|key,value| retry if text.gsub!(key,value)} # replace numerical entities starting with &# while true if res=text.match("&#x([0-9a-fA-F]+);") # hexadecimal text=res.pre_match+[res[1].hex].pack("U")+res.post_match elsif res=text.match("&#([0-9]+);") # decimal text=res.pre_match+[res[1].to_i].pack("U")+res.post_match else break end end end text end end