使用soaplib生成了错误的(?)数据类型
我在使用soaplib的时候遇到了一个问题。
我有一个由网络服务提供的函数:
@soap(Integer, Integer, _returns=Integer)
def test(self, n1, n2):
return n1 + n2
在生成的WSDL文件中,对应的数据类型声明是:
<xs:complexType name="test">
<xs:sequence>
<xs:element name="n1" type="xs:integer" minOccurs="0" nillable="true"/>
<xs:element name="n2" type="xs:integer" minOccurs="0" nillable="true"/>
</xs:sequence>
</xs:complexType>
<xs:complexType> name="testResponse">
<xs:sequence>
<xs:element name="testResult" type="xs:integer" minOccurs="0" nillable="true"/>
</xs:sequence>
</xs:complexType>
当我使用一些开发工具(比如Visual Studio或PowerBuilder)从这个WSDL文件生成代码时,不管用哪个工具,它都会生成两个类,一个是测试类,一个是测试响应类,它们的属性都是字符串类型。
有没有人知道我是否可以调整我的Python声明,以避免使用复杂类型,从而在客户端获得真正的整数类型?
3 个回答
好的,并不是所有的XSD数据类型都在soaplib中定义。整数类型在soaplib中是有定义的,在WSDL文件中显示为整数,但.NET框架(PowerBuilder使用的框架)却无法理解这个类型。
对于.NET/PowerBuilder来说,Int是可以的,但在soaplib中并没有定义这个类型。
所以,我决定从soaplib转到rpclib。这两个库非常相似(一个是另一个的分支)。
我检查了你的代码,但我得到的输出还是一样。我使用的是suds来解析这些值。
In [3]: from suds import client
In [4]: cl = client.Client('http://localhost:8080/?wsdl')
In [5]: cl.service.test(10,2)
Out[5]: 12
但是当我检查那个值的类型时。
In [6]: type(cl.service.test(10,2))
Out[6]: <class 'suds.sax.text.Text'>
所以SOAPLIB会返回字符串,但根据那个数据的类型你可以进行转换。
我通过写这个来检查响应
@soap(_returns=Integer)
def test(self):
return 12
所以我在Firefox的SOA客户端插件中得到的响应是
<?xml version='1.0' encoding='utf-8'?>
<senv:Envelope
xmlns:wsa="http://schemas.xmlsoap.org/ws/2003/03/addressing"
xmlns:plink="http://schemas.xmlsoap.org/ws/2003/05/partner-link/"
xmlns:xop="http://www.w3.org/2004/08/xop/include"
xmlns:senc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:s12env="http://www.w3.org/2003/05/soap-envelope/"
xmlns:s12enc="http://www.w3.org/2003/05/soap-encoding/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:senv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
<senv:Body>
<tns:testResponse>
<tns:testResult>
12
</tns:testResult>
</tns:testResponse>
</senv:Body>
</senv:Envelope>
从XML中你无法直接获取原始的整数数据。
我也遇到过同样的问题,但我没法摆脱soaplib。
所以,我用这种方式进行了修改:
from soaplib.serializers.primitive import Integer
class BetterInteger(Integer):
__type_name__ = "int"
Integer = BetterInteger
然后就继续我的生活了。
不过,XSD规范定义了两种类型:'integer':表示一个带符号的整数。这个值可以以可选的“+”或“-”符号开头。它是从十进制数据类型派生的。还有'int':表示一个32位的带符号整数,范围是[-2,147,483,648, 2,147,483,647]。它是从长整型数据类型派生的。
所以,更好的解决方案是:
from soaplib.serializers.primitive import Integer
class Int32(Integer):
__type_name__ = "int"
然后使用你新创建的'Int32'类来定义你的输入参数。
[soaplib 1.0.0]