问题
I am using savon 0.9.2 and ruby 1.8.7. I am trying to make a complex type soap request.
I need to figure out how to code the soap body for the below type of request using ruby and savon. Basically one of the complextypes in the request extends another type and also needs to be encoded as an array.
The soap request object is supposed to look like this.
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:app="http://someurl/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<soapenv:Header/>
<soapenv:Body>
<app:someMethod soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<xyzResReq xsi:type="java:xyzResReq" xmlns:java="java:com.xyz.request">
<somestring xsi:type="xsd:string">abc123</somestring>
<itinerary xsi:type="java1:xyzItinerary" xmlns:java1="java:com.xyz.domain">
<someList xsi:type="java2:List" soapenc:arrayType="xsd:anyType[]" xmlns:java2="java:language_builtins.util"/>
</itinerary>
</xyzResReq>
</app:someMethod>
</soapenv:Body>
</soapenv:Envelope>
someList is again a complextype in the schema form
<xsd:complexType name="someList">
<xsd:complexContent>
<xsd:extension base="stns:someBaseList">
<xsd:sequence>
<xsd:element maxOccurs="1" name="someElement" type="xsd:boolean" minOccurs="0" />
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
and someBaseList defined as
<xsd:complexType name="someBaseList">
<xsd:sequence>
<xsd:element maxOccurs="1" nillable="true" name="baseElement" type="xsd:string" minOccurs="0" />
</xsd:sequence>
</xsd:complexType>
How do I do this in savon.
回答1:
Savon is based on the assumption that most requests (XML) are simple enough to be abstracted as a Hash. In this complex example, I'd suggest two alternatives:
Instead of a Hash, you can use any Ruby object (that's not a Hash) and responds to
to_s
. So you could create an object (or a hierarchy of objects) with ato_s
method constructing the XML via something like Builder and pass it toSavon::SOAP::XML#body=
.class SomeXML def self.to_s "<some>xml</some>" end end client.request :some_action do soap.body = SomeXML end
You could also use
Savon::SOAP::XML#xml
, which yields a Builder instance to a given block to construct the XML "on the fly".client.request :some_action do soap.xml do |xml| xml.person { |b| b.name("Jim"); b.phone("555-1234") } end end
Hope that helps! Also, please take a look at the new Savon Guide.
来源:https://stackoverflow.com/questions/6267579/savon-soap-body-problem