我有一个SOAP API,我试图通过suds(python)调用一个方法:
DoSomething(ns1:DoSomethingRequest Input, )
DoSomethingRequest
看起来像这样:
(DoSomethingRequest){
Person =
(Person){
Name = "Joe"
Age = 32
}
ActionOne = None
ActionTwo = None
ActionThree = None
}
在类型定义中,动作参数都是可选的。要调用特定操作,请设置DoSomethingRequest.ActionOne = [an instance of ActionOneRequest]
。这很好(我可以执行ActionOne
),除了我试图调用ActionThree
,而ActionThreeRequest
是一个空的复杂元素。当我设置DoSomethingRequest.ActionThree = ActionThreeRequest
时,DoSomethingRequest
上的打印件会显示:
(DoSomethingRequest){
Person =
(Person){
Name = "Joe"
Age = 32
}
ActionOne = None
ActionTwo = None
ActionThree = <empty>
}
并且发送到服务器的XML排除了ActionThree
。如果我用pdb拦截代码并添加一个空元素<ActionThree></ActionThree>
,它就可以工作。
查看代码,为suds:
class ObjectAppender(Appender): """ An L{Object} appender. """ def append(self, parent, content): object = content.value if self.optional(content) and footprint(object) == 0: return child = self.node(content) parent.append(child) for item in object: cont = Content(tag=item[0], value=item[1]) Appender.append(self, child, cont)
和
def footprint(sobject): """ Get the I{virtual footprint} of the object. This is really a count of the attributes in the branch with a significant value. @param sobject: A suds object. @type sobject: L{Object} @return: The branch footprint. @rtype: int """ n = 0 for a in sobject.__keylist__: v = getattr(sobject, a) if v is None: continue if isinstance(v, Object): n += footprint(v) continue if hasattr(v, '__len__'): if len(v): n += 1 continue n +=1 return n
我不经常使用SOAP,所以我假设我正在使用API不正确,或者使用的是不正确的suds。或者,服务API可能是非标准的。
你知道为什么会有问题以及如何最好地解决它?
奇怪的是,相反的问题是SO:Suds generates empty elements; how to remove them?不幸的是,删除空元素要比找出哪些元素被删除并重新添加它们要容易得多。
谢谢!
答案 0 :(得分:2)
在阅读规范并与专家交谈后,我没有看到任何表明SOAP库可以删除可选的空元素的任何内容。
github上有一个补丁版的肥皂水。
答案 1 :(得分:1)
如果其他人遇到这个问题,并且没有找到答案。类似的情况发生在我身上。我试图在SOAP请求中发送以下正文,
<ns0:list><ns0:filter xsi:type="ns0:UserFilter"/></ns0:list>
我的第一次尝试,我使用suds.client.factory
创建了元素,并在没有配置的情况下发送它。这导致了以下机构,
<ns0:list><filter/></ns0:list>
我接下来尝试手动创建Element
并手动设置type
属性。那让我有了同样的信封。
在深入研究源代码后,我发现SoapClient.send()
方法正在sax.Document.plain()
方法中剥离我的属性。
查看代码,我发现我可以在suds客户端设置prettyxml=True
选项,并且不会剥离该属性。