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

Download the patch!

Comments

  1. Erik said about 1 hour later:
    Patching make things work :)

(leave url/email »)

   Preview comment