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



我正在向(内部)soap服务发送请求。我目前正在测试SUDS(Jurko's 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、郊区等元素包装在地址元素中,那么SUDS将正确封送响应。

或者,如果我使用suds DocumentPlugin钩子修改XSD(如下所示)以删除地址类型并包括单独的streetLine、郊区等元素,那么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库是否正确地指定/解释了document/literal与document/literial的包装(我不确定这在这里如何适用)。

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

原始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中也称为"address",属于上面定义的类型"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:address类型定义的情况下编写的地理编码地址的等价物是这样的:

<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

如果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>

最新更新