require 'libxml' module LibXML module XML module Conversions module Document def to_hash root.to_hash end end module Node CONTENT_ROOT = '__content__' def to_hash(hash={}) if text? hash[CONTENT_ROOT] = content else hash[name] = sub_hash = {} attributes_to_hash(sub_hash) if array? children_array_to_hash(sub_hash) else children_to_hash(sub_hash) end end hash end protected def children_to_hash(hash={}) each { |child| child.to_hash(hash) } hash end def attributes_to_hash(hash={}) each_attr { |attr| hash[attr.name] = attr.value } hash end def children_array_to_hash(hash={}) hash[child.name] = map do |child| returning({}) { |sub_hash| child.children_to_hash(sub_hash) } end hash end def array? child? && child.next? && child.name == child.next.name end end end end end LibXML::XML::Document.send(:include, LibXML::XML::Conversions::Document) LibXML::XML::Node.send(:include, LibXML::XML::Conversions::Node) module ActiveSupport module CoreExtensions module Hash module Conversions module ClassMethods # libxml def from_xml(xml) xml.gsub!(/\s*\n\s*/, '') typecast_xml_value(undasherize_keys(LibXML::XML::Parser.string(xml).parse.to_hash)) end end end end end end