我尝试执行以下代码,但xmlrpclib
引发了异常:
>>> import xmlrpclib
>>> data = """<?xml version="1.0"?>
... <methodCall>
... <methodName>test_method</methodName>
... <params>
... <param>
... <value>
... <int/>
... </value>
... </param>
... </params>
... </methodCall>"""
>>> xmlrpclib.loads(data)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python2.7/xmlrpclib.py", line 1141, in loads
p.feed(data)
File "/usr/lib64/python2.7/xmlrpclib.py", line 558, in feed
self._parser.Parse(data, 0)
File "/usr/lib64/python2.7/xmlrpclib.py", line 829, in end
return f(self, join(self._data, ""))
File "/usr/lib64/python2.7/xmlrpclib.py", line 864, in end_int
self.append(int(data))
ValueError: invalid literal for int() with base 10: ''
如果我将<int/>
替换为<int></int>
,则错误相同;但是<int>0</int>
没有引发异常。使用xmlrpc.client
的python3中的结果相同。
我尝试用PHP做同样的事情,它没有任何麻烦:
php > $data = '<?xml version="1.0"?><methodCall><methodName>test_method</methodName><params><param><value><int/></value></param></params></methodCall>';
php > print_r(xmlrpc_decode($data));
Array
(
[0] => 0
)
.NET实现中的documentation也意味着<int/>
将被转换为0:
如果缺少XML-RPC结构成员,则如果使用了非可空类型,则其对应的.NET结构成员将设置为null而不是该类型的默认值,例如对于整数,为null而不是零
这种行为是否是Python实现中的错误?
答案 0 :(得分:2)
没有对Python实现做出判断:)这个猴子补丁修复了end_int()处理空数据的方式。在调用xmlrpclib.loads(data)之前的示例中:
class MyUnmarshaller(xmlrpclib.Unmarshaller):
def end_int(self, data):
self.append(int(data or "0"))
self._value = 0
dispatch = xmlrpclib.Unmarshaller.dispatch
dispatch["i4"] = end_int
dispatch["i8"] = end_int
dispatch["int"] = end_int
xmlrpclib.Unmarshaller = MyUnmarshaller