使用soaplib生成了错误的(?)数据类型

1 投票
3 回答
620 浏览
提问于 2025-04-17 04:00

我在使用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 个回答

1

好的,并不是所有的XSD数据类型都在soaplib中定义。整数类型在soaplib中是有定义的,在WSDL文件中显示为整数,但.NET框架(PowerBuilder使用的框架)却无法理解这个类型。

对于.NET/PowerBuilder来说,Int是可以的,但在soaplib中并没有定义这个类型。

所以,我决定从soaplib转到rpclib。这两个库非常相似(一个是另一个的分支)。

2

我检查了你的代码,但我得到的输出还是一样。我使用的是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中你无法直接获取原始的整数数据。

0

我也遇到过同样的问题,但我没法摆脱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]

撰写回答