Savon soap body problem

落花浮王杯 提交于 2020-01-15 06:49:52

问题


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:

  1. 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 a to_s method constructing the XML via something like Builder and pass it to Savon::SOAP::XML#body=.

    class SomeXML
      def self.to_s
        "<some>xml</some>"
      end
    end
    
    client.request :some_action do
      soap.body = SomeXML
    end
    
  2. 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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!