我几天来一直无法解决这个问题,并且无法在互联网上找到任何有用的资源,所以我将在此事上分享我的发现以供将来参考:
Python 2.7 xmlrpclib
客户端具有内置的XMLRPC标准定义的类型,以及一些常见的扩展。然而,其他XMLRPC服务器(如Apache)有时会使用自己的类型,或者将扩展放在特殊的命名空间中等。
例如,当您使用Apache发送一个8字节整数(XMLRPC标准未涵盖)时,它将发送以下响应:
<methodResponse xmlns:ex="http://ws.apache.org/xmlrpc/namespaces/extensions">
<params>
<param>
<value>
<ex:i8>123456789</ex:i8>
</value>
</param>
</params>
</methodResponse>
如果您天真地尝试使用Python处理这些类型,您将获得一个空的元组结果。如何调整xmlrpclib
来处理此类案件?
答案 0 :(得分:4)
在内部,xmlrpclib
使用xmlrpclib.Unmarshaller
来发送回复。 Unmarshaller
有一个dispatch
字典,其中每个类型都分配了一个处理它的函数。
让问题的示例工作实际上非常简单,因为xmlrpclib
已经可以处理i8
而我们只需将ex:i8
重新映射到:{/ p>
xmlrpclib.Unmarshaller.dispatch['ex:i8'] = xmlrpclib.Unmarshaller.dispatch['i8']
但是对于更多自定义类型,可能需要编写调度函数。这些被设计为在Unmarshaller
内定义,因此典型的调度函数如下所示:
def end_int(self, data):
self.append(int(data))
self._value = 0
dispatch['i8'] = end_int
_value = 0
只表示调度成功。所以,如果我们有
<methodResponse>
<params>
<param>
<value>
<mycustom>some value</mycustom>
</value>
</param>
</params>
</methodResponse>
我们可以定义:
def mycustom_parser(unmarshaller, data):
unmarshaller.append(data.split())
unmarshaller._value = 0
xmlrpclib.Unmarshaller.dispatch['mycustom'] = mycustom_parser