此SOAP响应是否与WSDL / XSD一致?

时间:2014-02-28 02:19:25

标签: python soap suds

我正在向(内部)肥皂服务发送请求。我目前正在测试SUDS(Jurko的fork)和OSA python soap库。两人都无法调整回应。

对成功请求的原始xml响应是:

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
  <S:Body>
    <ns2:geocodeAddressResponse xmlns:ns2="http://geocodegateway">
      <geocodedAddress>
        <streetLine>1 SOME STREET</streetLine>
        <suburb>SOMEBURB</suburb>
        <state>SS</state>
        <postcode>1234</postcode>
        <x>111.222222</x>
        <y>-22.333333</y>
      </geocodedAddress>       
etc...

OSA和SUDS库都引发了异常:

  • OSA例外是ValueError: 'streetLine' is not in list
  • SUDS例外是TypeNotFound: Type not found: 'streetLine'

soap服务的XSD(由WSDL导入)是:

<?xml version="1.0" encoding="UTF-8"?><!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.7-b01-. --><xs:schema xmlns:gns="http://geocodegateway" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="1.0" targetNamespace="http://geocodegateway">
  <xs:element name="address" nillable="true" type="gns:address"></xs:element>
  <xs:element name="geocodeAddressRequest" nillable="true" type="gns:geocodeAddressRequest"></xs:element>
  <xs:element name="geocodeAddressResponse" nillable="true" type="gns:geocodeAddressResponse"></xs:element>
  <xs:complexType name="address">
    <xs:sequence>
      <xs:element name="streetLine" type="xs:string"></xs:element>
      <xs:element name="suburb" type="xs:string"></xs:element>
      <xs:element name="state" type="xs:string"></xs:element>
      <xs:element name="postcode" type="xs:string"></xs:element>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="geocodeAddressRequest">
    <xs:sequence>
      <xs:element name="appId" type="xs:string"></xs:element>
      <xs:element name="address" nillable="true" type="gns:address"></xs:element>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="geocodeAddressResponse">
    <xs:sequence>
      <xs:element name="responseCode" type="xs:string" maxOccurs="1" minOccurs="1"></xs:element>
      <xs:element name="geocodedAddress">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="address" nillable="true" type="gns:address"></xs:element>
            <xs:element name="x" type="xs:string"></xs:element>
            <xs:element name="y" type="xs:string"></xs:element>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

如果我通过SUDS MessagePlugin挂钩修改响应XML以将streetLine,suburb等元素包装在地址元素中,那么SUDS会正确地编组响应。

或者,如果我使用suds DocumentPlugin钩子(如下所示)修改XSD以删除地址类型并包含单独的streetLine,suburb等元素,那么SUDS会正确地编组响应。

<xs:complexType name="geocodeAddressResponse">
  <xs:sequence>
    <xs:element name="responseCode" type="xs:string" maxOccurs="1" minOccurs="1"/>
    <xs:element name="geocodedAddress">
      <xs:complexType>
        <xs:sequence>
          <xs:element name="streetLine" type="xs:string"></xs:element>
          <xs:element name="suburb" type="xs:string"></xs:element>
          <xs:element name="state" type="xs:string"></xs:element>
          <xs:element name="postcode" type="xs:string"></xs:element>
          <xs:element name="x" type="xs:string"></xs:element>
          <xs:element name="y" type="xs:string"></xs:element>
        </xs:sequence>
      </xs:complexType>
    </xs:element>
  </xs:sequence>
</xs:complexType>

我向soap服务的开发人员建议,可能应该修改XSD或XML响应,使它们保持一致但是被告知它们似乎是正确的,并检查我正在使用的python soap库是否指定/解释文档/文字与文档/文字正确包装(我不确定这在哪里适用)。

问题:SOAP响应是否与WSDL / XSD一致,而python soap库是否正确解释它(或者我没有正确使用它们)?

2 个答案:

答案 0 :(得分:1)

原始XML响应不与WSDL内联。

类型和元素之间可能存在混淆:

WSDL中捆绑的这部分XSD定义了一个名为“address”的类型

 <xs:complexType name="address">
    <xs:sequence>
        <xs:element name="streetLine" type="xs:string"></xs:element>
        <xs:element name="suburb" type="xs:string"></xs:element>
        <xs:element name="state" type="xs:string"></xs:element>
        <xs:element name="postcode" type="xs:string"></xs:element>
   </xs:sequence>
 </xs:complexType>

而相同XSD的这一部分定义了一个元素,它在geocodedAddress中也称为“地址”,并且是上面定义的 type “address”:

 <xs:element name="geocodedAddress">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="address" nillable="true" type="gns:address"></xs:element>

因此,根据该定义,原始肥皂响应应如下所示:

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
  <S:Body>
    <ns2:geocodeAddressResponse xmlns:ns2="http://geocodegateway">
      <geocodedAddress>
        <address>
            <streetLine>1 SOME STREET</streetLine>
            <suburb>SOMEBURB</suburb>
            <state>SS</state>
            <postcode>1234</postcode>
            <x>111.222222</x>
            <y>-22.333333</y>
        </address>
      </geocodedAddress>  

并且没有单独的gns:地址类型定义的geocodedAddress的等价物将是这样的:

<xs:complexType name="geocodeAddressResponse">
  <xs:sequence>
    <xs:element name="responseCode" type="xs:string" maxOccurs="1" minOccurs="1"/>
    <xs:element name="geocodedAddress">
      <xs:complexType>
        <xs:sequence>
          <xs:element name="address">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="streetLine" type="xs:string"></xs:element>
                <xs:element name="suburb" type="xs:string"></xs:element>
                <xs:element name="state" type="xs:string"></xs:element>
                <xs:element name="postcode" type="xs:string"></xs:element>
                <xs:element name="x" type="xs:string"></xs:element>
                <xs:element name="y" type="xs:string"></xs:element>
              </xs:sequence>
            </xs:complexType>
          </xs:element>
        </xs:sequence>
      </xs:complexType>
    </xs:element>
  </xs:sequence>
</xs:complexType>

答案 1 :(得分:1)

你是对的,这不一致。

选项1

如果XSD看起来像这样:

  <xs:element name="geocodedAddress">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="address" nillable="true" type="gns:address"></xs:element>
        <xs:element name="x" type="xs:string"></xs:element>
        <xs:element name="y" type="xs:string"></xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

XML应如下所示:

  <geocodedAddress>
     <address>
        <streetLine>Street 1</streetLine>
        <suburb>Suburb 1</suburb>
        <state>XX</state>
        <postcode>1234</postcode>
     </address>
     <x>111.11</x>
     <y>-22.22</y>
  </geocodedAddress>

选项2

如果XSD看起来像这样:

<xs:element name="geocodedAddress">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="streetLine" type="xs:string"></xs:element>
      <xs:element name="suburb" type="xs:string"></xs:element>
      <xs:element name="state" type="xs:string"></xs:element>
      <xs:element name="postcode" type="xs:string"></xs:element>
      <xs:element name="x" type="xs:string"></xs:element>
      <xs:element name="y" type="xs:string"></xs:element>
    </xs:sequence>
  </xs:complexType>
</xs:element>

XML应如下所示:

  <geocodedAddress>
      <streetLine>Street 1</streetLine>
      <suburb>Suburb 1</suburb>
      <state>XX</state>
      <postcode>1234</postcode>
      <x>111.11</x>
      <y>-22.22</y>
  </geocodedAddress>