我正在尝试向soap服务器发送请求,使用的suds应如下所示:
<SOAP-ENV:Envelope xmlns:ns0="http://example.com/wsdl/abc/model/v1" xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns2="http://example.com/xsd/abc/common/v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<ns1:Body>
<ns0:myMethod>
<unique_id>5211c04b-9cf5-4368-a393-ed96d7b5489d</unique_id>
<metadata>
<ns2:StringMetadata id="user">test_user</ns2:StringMetadata>
<ns2:StringMetadata id="filename">myfile.zip</ns2:StringMetadata>
<ns2:StringMetadata id="unique_id">5211c04b-9cf5-4368-a393-ed96d7b5489d</ns2:StringMetadata>
</metadata>
</ns0:myMethod>
</ns1:Body>
有没有办法通过 only dict来实现?
我正在尝试这个:
params = {
'unique_id' : uid,
"metadata": {
'StringMetadata' : ['test_user', 'myfile.zip']
}
}
caller.myMethod(**params)
生成此请求:
<SOAP-ENV:Envelope xmlns:ns0="http://example.com/wsdl/abc/model/v1" xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns2="http://example.com/xsd/abc/common/v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<ns1:Body>
<ns0:myMethod>
<unique_id>2ae5a60e-7928-4d4f-9e53-bafe2a003b8a</unique_id>
<metadata>
<ns2:StringMetadata>test_user</ns2:StringMetadata>
<ns2:StringMetadata>myfile.zip</ns2:StringMetadata>
</metadata>
</ns0:myMethod>
</ns1:Body>
</SOAP-ENV:Envelope>
因此我们可以看到 StringMetada 中缺少 id 属性。我想使用 only dict来做这件事,因为我正在编写一种Rest to Soap代理,它从另一个调用者那里得到一个未经验证的Json(或dict)。所以它应该尽可能的动态。
我试图在fly元素上构建(使用factory.create),但它似乎很头疼......我希望通过传递元素属性的特殊关键字('_id','@ id'或'#ID')...
我也试图像这样声明我的StringMetadata:
"metadata": {
'StringMetadata' : [{'_id': 'user'}, 'myfile.zip']
}
但它给了我:
<ns2:StringMetadata id="user"/>
<ns2:StringMetadata>myfile.zip</ns2:StringMetadata>
如果你有一个解决方案,通过将猴子补丁(飞行中)应用到肥皂水池,请随意。
此致
答案 0 :(得分:0)
我终于设法让它在经过数小时的理解和调试后工作。我写了一个基于肥皂猴补丁的解决方案。因此,我的命令应该是:
params = {
'unique_id' : uid,
"metadata": {
'StringMetadata' : [{'_id': 'user', '_text_':'test_user'},{'_id': 'filename', '_text_': 'myfile.zip'}]
}
}
caller.myMethod(**params)
&#39;的 _text _ 强>&#39;是一个神奇的,将被补丁检测并用作节点值。 &#39; _id &#39;将suds用作属性,以_开头的每个元素都被解释为节点属性,因此我的补丁不会处理属性。
这是补丁:
import functools
from suds.mx.appender import *
legacy_append = suds.mx.appender.ObjectAppender.append
@functools.wraps(legacy_append)
def _patch_object_append(self, parent, content):
object = content.value
if self.optional(content) and footprint(object) == 0:
return
child = self.node(content)
for item in object:
cont = Content(tag=item[0], value=item[1])
if item[0] == '_text_':
child.setText(item[1])
continue
Appender.append(self, child, cont)
parent.append(child)
suds.mx.appender.ObjectAppender.append= _patch_object_append
可以在suds实例化之前插入此块,也可以将其存储在单独的脚本文件中并导入脚本中。就个人而言,我使用了第二种解决方案。
另请注意,关键字文字是我的选择,您可以使用&#39; _value _ &#39;代替。它应该在这一行更新:
if item[0] == '_text_':
请随意使用此补丁。我认为这个功能应该内置在Suds库中
此致