libXML and activeresource revisited
Posted by Pieter Bos Thu, 26 Jun 2008 08:32:58 GMT
A while ago, an article was posted on this blog by Bart which showed how activeresource can be sped up with libXML. However, this patch was not complete and broken in rails 2.1. So Brian Guthrie made a new patch. However, this patch also has an issue:
If you parse an xml file containing the google weather api for example, you get something like:
<weather>
<current_conditions></current_conditions>
<forecast_conditions><low data="10"/></forecast_conditions>
<forecast_conditions><low data="12"/></forecast_conditions>
</weather>
to an object with a single forecast_conditions object with the low temperature at 12 degrees.
So, i created a simple patch:
def to_hash(hash={})
#if there is already an entry with the given name, switch
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
This replaces the line that just overwrites the previous hash with one that creates an array if required. Also, libxml doesn't like empty files. So much that it just segmentation faults on empty input. So we add to the from_xml method:
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

Patching make things work :)
What a world it will be without patching :)