begin require 'xml/libxml' # This is actally a fix for activeresource as it # will behave incorrectly when it encounters # Complex xml files. This override fixes this, # but it should be submitted to rails trunk. module ActiveSupport module CoreExtensions module Hash module Conversions module ClassMethods # libxml def from_xml(xml) xml.gsub!(/\s*\n\s*/, '') if(xml.blank?) return {} else typecast_xml_value(undasherize_keys(XML::Parser.string(xml).parse.to_hash)) end end end end end end end module XML module Conversions module Document def to_hash root.to_hash end end module Node CONTENT_ROOT = '__content__' def to_hash(hash={}) #if there is already an entry with the given name, switch it if text? hash[CONTENT_ROOT] = content else sub_hash = insert_name_into_hash(hash, name) 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 insert_name_into_hash(hash, name) sub_hash = {} if hash[name] if !hash[name].kind_of? Array hash[name] = [hash[name]] end hash[name] << sub_hash else hash[name] = sub_hash end sub_hash end 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 XML::Document.send(:include, XML::Conversions::Document) XML::Node.send(:include, XML::Conversions::Node) rescue end