We decided that it would be best to write a RESTful service facade to front the SOAP service instead. Trying to flesh it out quickly, I turned to Ruby with soap4r, whereupon I ran smack into a problem that took me a few days to track down the resolution to.
The soap request needed to look something like this:
Simple, right? Well the hard part is the attribute. WSDLDriverFactory is not well documented. Actually, I don't think it is documented at all, but I found examples on the web of how to use it. You pass your soap method a map of the values, like this:
{:rootElement => {:childElement => {:myId => "123456"}}}That works great if "myId" is an element contained by childElement, but in our case it's an attribute. How do you tell the proxy that myId is the value of an attribute, not the valude of an element? You would think that it would be smart enough to figure it out, but it's not. After digging around for hours, I finally found an obscure reference to the answer: you have to prefix the attribute name with "xmlattr_". So the correct map looks like this:
{:rootElement => {:childElement => {:xmlattr_myId => "123456"}}}The full code looks like:
require 'soap/wsdlDriver' wsdl = 'http://host:port/some-service?WSDL' client = SOAP::WSDLDriverFactory.new( wsdl ).create_rpc_driver client.wiredump_dev = $stdout client.options["protocol.http.basic_auth"] << [wsdl, 'MY_USER', 'MY_PASSWORD'] result = client.doSomething( {:rootElement => {:childElement => {:xmlattr_myId => "123456"}}})