# -*- coding: utf-8 -*- require 'rubygems' require 'hpricot' # Apricot eats Gorilla converts SOAP response messages to Ruby hashes. # It's based on CobraVsMongoose but uses Hpricot instead of REXML and it # also doesn't follow the BadgerFish convention. class ApricotEatsGorilla # Converts a given SOAP response message into a Ruby Hash. def self.soap_response_to_hash(xml, root_node = nil) xml = prepare_xml(xml) root_node ||= "//return" doc = Hpricot.XML(xml) xml_node_to_hash doc.at(root_node) end private # Converts XML nodes into a Ruby Hash. Recursively calls itself to grab # nested XML nodes and values. def self.xml_node_to_hash(node) this_node = {} node.each_child do |child| if child.children.nil? key, value = child.name, nil elsif child.children.size == 1 && child.children.first.text? key, value = child.name, string_to_bool?(child.children.first.raw_string) else key, value = child.name, xml_node_to_hash(child) end current = this_node[key] case current when Array: this_node[key] << value when nil this_node[key] = value else this_node[key] = [current.dup, value] end end this_node end # Helper to remove line breaks and whitespace between XML nodes. def self.prepare_xml(xml) xml = xml.gsub(/\n+/, "") xml = xml.gsub(/(>)\s*(<)/, '\1\2') end # Helper to convert "true" and "false" strings to boolean values. # Returns the original string in case it doesn't match "true" or "false". def self.string_to_bool?(string) return true if string == "true" return false if string == "false" string end end