savonrb / savon

Heavy metal SOAP client
https://www.savonrb.com
MIT License
2.07k stars 616 forks source link

setting id in XML #7

Closed cambridgemike closed 14 years ago

cambridgemike commented 14 years ago

The API i'm working with requires me to set the id field inside of a tag in the body. So it needs to look something like this:

Is there a way to do this in the hash i'm passing in, or am I going to have to build the body as an XML doc and pass that in (suboptimal).

thanks!

mike

rubiii commented 14 years ago

i agree that using xml is "suboptimal" and i'm sorry, but right now there is no way to specify xml attributes via a soap body hash.

m1k3 commented 14 years ago

This should be resolved, as having a nice dsl to specify the params is one of the great features of this library. Not being able to use it on relatively simple stuff really sucks :(

andrewmbenton commented 14 years ago

I think I would like to do a similar thing. It's nice to be able to use the input method on the soap object since it's automatically namespaced correctly, but not being able to pass a hash of attributes and values to the tag is forcing me into a workaround for those requests that require it. I may fork this and propose a fix...

cambridgemike commented 14 years ago

I'm not a ruby wizard, but could you extend the String or Object class to have accessor "attribute_id". Then you could do something like this...

body[:customerreference] = "Mike" body[:customerreference].attribute_id = 1

which would translate to:

After looking at the source I think the hard part will be extending the to_soap_xml method in the core_extras/hash, but I might take a stab at it.

Stanleydrew, what were you thinking?

andrewmbenton commented 14 years ago

@cambridgemike, I can work around most stuff in the body just by constructing a clever hash to pass in. My problem is that i need to put some attributes on the "root" element within the SOAP body, so I need something that looks like: env:Body

... /wsdl:someRequest /env:Body Right now the savon api only allows a single element tag name assigned to the input instance variable of the soap object, as in: response = @savon_client.some_request! do |req| req.namespace = @namespace req.action = "someRequest" req.input = "some-request" end Seems like the most elegant fix might be to expose a little more of the underlying Builder::XmlMarkup object for those who require more flexibility than a simple hash can provide
rubiii commented 14 years ago

hey guys, thanks for actually talking about the issue and how it could be fixed. as far as i can see, (at least right now). these are actually two different problems.

first, there's a problem of having to set attributes to the root node, which could be solved by exposing the buildr code or by extending the soap.input method with an optional hash for example.

the second one is about setting attributes on the input hash and i think adding some kind of attribute method to the hash class might be an idea.

i'll definitely think about both and try to come up with a solution next weekend. but please keep on commenting in case you have a better idea. i'd really like to hear those.

cambridgemike commented 14 years ago

neat, I created a fork and implemented the change I proposed (mostly because I wanted to learn how to fork...), feel free to take a look, it works as described in earlier post. http://github.com/cambridgemike/savon

andrewmbenton commented 14 years ago

@rubiii You are right that these are technically different, but very related problems. I will fork and extend the soap.input method to accept a hash which is then just directly passed to the xmlbuilder object. that will solve my problem. then i'll take a look at cambridgemike's fork to see how he solved the problem generally for any element within the body.

andrewmbenton commented 14 years ago

OK here's the commit from my fork (turned out to be a one line edit to the input_array method): http://github.com/stanleydrew/savon/commit/86d06e216f5c9fdde8a33ad0666db1929fe8a8c1 Now you can do the following: soap.input = "someRequest", {"someAttribute"=>"someValue", ...} to get: <wsdl:someRequest someAttribute="someValue" ...> ... /wsdl:someRequest This way the Savon api doesn't change. You can still assign a single string to soap.input. There's just added functionality now.

I've never done this on github before... Am i supposed to issue a pull request now?

cambridgemike commented 14 years ago

I had a chat with rubii about setting ids and attributes within the body of the soap request, and agreed that it might be worth some more planning before implementing in master. Disregard my fork for now, unless you desperately need a quick fix before the weekend.

rubiii commented 14 years ago

please refer to http://github.com/rubiii/savon/issues#issue/35 for more information about this feature.

rubiii commented 14 years ago

this should work already. please take a look at the documentation.

Ramanpreetsingh commented 6 years ago

Can anyone post the proposed fix for this, as the link http://github.com/rubiii/savon/issues#issue/35 is not working.