SOAP suds 和令人头疼的模式类型未找到错误
我第一次使用最新版本的suds(https://fedorahosted.org/suds/),结果在第一步就卡住了。
suds.TypeNotFound: Type not found: '(schema, http://www.w3.org/2001/XMLSchema, )'
我知道在suds的世界里,这个问题已经被讨论得很透彻了(https://fedorahosted.org/suds/wiki/TipsAndTricks#Schema-TypeNotFound 和 Python/Suds: 找不到类型: 'xs:complexType'),但我遇到的情况似乎有点不同,因为(a)在0.3.4版本之后,schema应该是自动绑定的,(b)即使我明确使用了解决方法,还是不行。
from suds.client import Client
from suds.xsd.sxbasic import Import
url = 'file:wsdl.wsdl'
Import.bind('http://schemas.xmlsoap.org/soap/encoding/')
client = Client(url, cache = None)
使用这个wsdl:
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
xmlns:tns="http://ws.client.com/Members.asmx"
xmlns:s="http://www.w3.org/2001/XMLSchema"
xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
targetNamespace="http://ws.client.com/Members.asmx"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://ws.client.com/Members.asmx">
<s:element name="GetCategoriesResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="GetCategoriesResult">
<s:complexType>
<s:sequence>
<s:element ref="s:schema" />
<s:any />
</s:sequence>
</s:complexType>
</s:element>
</s:sequence>
</s:complexType>
</s:element>
</s:schema>
</wsdl:types>
</wsdl:definitions>
会抛出上面的异常。
3 个回答
对于那些仍然被这个问题困扰的人,这个链接 https://bitbucket.org/jurko/suds/issue/20/typenotfound-schema 可能会提供一些有用的信息。解决方案大概是这样的:
from suds.client import Client
from suds.xsd.doctor import Import, ImportDoctor
url = 'http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl'
imp = Import('http://www.w3.org/2001/XMLSchema',
location='http://www.w3.org/2001/XMLSchema.xsd')
imp.filter.add('http://WebXml.com.cn/')
client = Client(url, doctor=ImportDoctor(imp))
我在这个问题上纠结了很久,最后通过以下方式解决了这个问题:
from suds.xsd.doctor import ImportDoctor, Import
url = 'http://somedomain.com/filename.php?wsdl'
imp = Import('http://schemas.xmlsoap.org/soap/encoding/')
imp.filter.add('http://some/namespace/A')
doctor = ImportDoctor(imp)
client = Client(url, doctor=doctor)
首先,从网址开始。把那个文件在浏览器里打开,它会给你提供wsdl的定义。确保你输入的网址是正确的,并且确实能打开一个XML文件。还要注意网址最后的?wsdl。
第二,imp = Import('http://schemas.xmlsoap.org/soap/encoding/')
这行代码会导入标准的SOAP架构。
第三,imp.filter.add('http:somedomain.com/A')
这行代码会添加你特定的命名空间。你可以通过在上面定义的url=
中打开的网址,找到<wsdl:import namespace="http://somedomain.com/A"
这一部分来找到这个命名空间的位置。
另外,要注意你网址中的http和https的区别。
我们把这个搞定了,希望你也成功了,虽然这个过程有点奇怪。也许明确指定位置或使用过滤器会有所帮助。例如:
imp = Import(
'http://schemas.xmlsoap.org/soap/encoding/',
location='http://schemas.xmlsoap.org/soap/encoding/'
)
imp.filter.add('http://ws.client.com/Members.asmx')
client = Client(url, plugins=[ImportDoctor(imp)])