Reputation: 8975
I've been having trouble solving this problem for days, and wasn't able to find any useful resource on this on the internet, so I'll share my findings on this matter for future reference:
The Python 2.7 xmlrpclib
client has the types defined by the XMLRPC standard built-in, plus a few common extensions. Other XMLRPC-servers, such as Apache, will however sometimes use their own types, or put extensions in special namespaces, etc.
For example, when you send an 8 byte integer with Apache (which is not covered by the XMLRPC standard), it will send the following response:
<methodResponse xmlns:ex="http://ws.apache.org/xmlrpc/namespaces/extensions">
<params>
<param>
<value>
<ex:i8>123456789</ex:i8>
</value>
</param>
</params>
</methodResponse>
If you naively try to handle these types with Python you will get an empty tuple result. How can I adjust xmlrpclib
to handle such cases?
Upvotes: 3
Views: 769
Reputation: 8975
Internally, xmlrpclib
uses the xmlrpclib.Unmarshaller
to dispatch responses. The Unmarshaller
has a dispatch
dictionary in which each type is assigned a function that will handle it.
Getting the question's example to work is actually quite easy, because xmlrpclib
can already handle i8
and we only have to remap ex:i8
to that:
xmlrpclib.Unmarshaller.dispatch['ex:i8'] = xmlrpclib.Unmarshaller.dispatch['i8']
But for more custom types it might be necessary to write on dispatch functions. Those are designed to be defined within Unmarshaller
, so a typical dispatch function looks like this:
def end_int(self, data):
self.append(int(data))
self._value = 0
dispatch['i8'] = end_int
_value = 0
just indicates that dispatching was successful. So if we had
<methodResponse>
<params>
<param>
<value>
<mycustom>some value</mycustom>
</value>
</param>
</params>
</methodResponse>
we could define:
def mycustom_parser(unmarshaller, data):
unmarshaller.append(data.split())
unmarshaller._value = 0
xmlrpclib.Unmarshaller.dispatch['mycustom'] = mycustom_parser
Upvotes: 4