2016-01-20 113 views
1

我试图发送到SOAP服务器的请求,使用肥皂水这应该是这样的:如何字典转化为泡沫复合泡沫型

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

有没有办法做到这一点通过使用只有字典?

我想这一点:

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> 

所以我们本身的ID属性是从我的StringMetada失踪。我想这样做只使用字典,因为我正在写一种Rest to Soap代理,它从另一个调用方获取未验证的Json(或字典)。所以它应该尽可能动态。我试着建立在飞行元素(与factory.create),但它似乎是一个头痛......我将不胜感激解决方案通过传递一个特殊的关键字的元素属性('_id','@id'或 '#ID')......

我也试图声明我StringMetadata这样的:

"metadata": { 
     'StringMetadata' : [{'_id': 'user'}, 'myfile.zip'] 
    } 

,但它给了我:

<ns2:StringMetadata id="user"/> 
    <ns2:StringMetadata>myfile.zip</ns2:StringMetadata> 

如果你有一个解决方案,通过应用一个猴子补丁(在飞行)去泡课,请随时免费。

问候

回答

0

我终于设法得到它的肥皂水理解和调试小时后工作。我写了一个基于泡沫猴子补丁的解决方案。因此,我的字典应该是:

params = { 
'unique_id' : uid, 
"metadata": { 
     'StringMetadata' : [{'_id': 'user', '_text_':'test_user'},{'_id': 'filename', '_text_': 'myfile.zip'}] 
    } 
} 

caller.myMethod(**params) 

_text_”是将由该补丁被检测到并用作节点值的魔法。 '_id'将被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 

该块可以在泡沫实例化之前插入或者存储在分离的脚本文件,并在脚本导入。我个人使用第二种解决方案。

请注意,关键字文本是我的选择,您可以使用'_value_'代替。它应该更新在这一行:

 if item[0] == '_text_': 

请随时使用此修补程序。我认为这个功能应该内置在Suds库中

Regards,