【问题标题】:Is this SOAP response consistent with the WSDL/XSD?这个 SOAP 响应是否与 WSDL/XSD 一致?
【发布时间】:2014-02-28 02:19:24
【问题描述】:

我正在向(内部)soap 服务发送请求。我目前正在测试SUDS(Jurko 的叉子)和OSA python 肥皂库。两者都无法编组响应。

对成功请求的原始 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、郊区等元素包装在地址元素中,那么 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响应以使它们保持一致,但被告知它们似乎是正确的并检查我正在使用的pythonsoap库是否指定/interpreting document/literal vs document/literal 正确包装(我不确定这在这里如何应用)。

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

【问题讨论】:

    标签: python soap suds


    【解决方案1】:

    原始 XML 响应没有与 WSDL 内联。

    也许类型和元素之间存在混淆:

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

     <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 中也称为“地址”,并且属于上面定义的 类型“地址”:

     <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:address 类型定义的 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>
    

    【讨论】:

      【解决方案2】:

      你是对的,这并不一致。

      选项 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>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多