SOAP4R is the Ruby SOAP toolkit making it easy to prop up a web service or set up a client to access a remote API. Hpricot is an amazing HTML/XML parser. It has a C back-end and is extremely fast (I would say it’s faster then libxml wrapper in my opinion). But what happens when you want to send an XML document over SOAP without SOAP4R mucking it all up (in most cases SOAP4R will just choke and leave you with some obscure “Can’t translate crocodiles into SOAP::Object” message. Alas, in version 1.5.8 SOAP4R has the ability to simply wrap the XML and send it on its way.
Cool huh? Oh wait, you can only use REXML Documents/Elements for this, and as we all know REXML is not really a speed demon. Besides if the rest of your code uses Hpricot why switch to REXML and back again just for SOAP stuff. Well, the key in the paragraph describing the XML pass-through feature is “… or any class with ‘to_xmlpart’ method”. Hpricot::Doc doesn’t have ‘to_xmlpart’ method, but you wouldn’t really need out. Behold the following:
xml_container.rb:
class XMLContainer
def initialize(xml)
@xml = xml
end
def to_xmlpart
@xml
end
end
XMLContainer class has ‘to_xml’ method and thus can be passed directly into SOAP4R calls without the fear of blow-up:
require 'xml_container'
require 'hpricot'
require 'soap/rpc/driver'
# Do SOAP initialization here and get the RPC driver ready to make SOAP calls
# ...
xml_doc = Hpricot::XML(File.read("MyXML.xml"))
xml_can = XMLContainer.new xml_doc.to_html
soapdriver->add_method("SendStuff","myXml")
soapdriver->SendStuff xml_can
And there you go. Have fun kids
Correction: in the newest version of SOAP4R they changed the method from to_xml to to_xmlpart. I’ve update the code above to reflect that change.
Posted by mzolin 

