为什么Jython 2.5.2中的xml.sax解析器将两个字符的属性转换为元组?
每当我在用 Jython 2.5.2 解析 XML 时,遇到一个两个字符的属性,它就会把这个属性名转换成一个元组。无论我怎么尝试,都无法提取到这个属性的值。我试过把元组传过去,或者把它转换成字符串再传,但结果都是:
Traceback (most recent call last):
File "test.py", line 18, in startElement
print '%s = %s' % (k, attrs.getValue(k))
File "/usr/local/Cellar/jython/2.5.2/libexec/Lib/xml/sax/drivers2/drv_javasax.py", line 266, in getValue
value = self._attrs.getValue(_makeJavaNsTuple(name))
TypeError: getValue(): 1st arg can't be coerced to String, int
我有一些示例代码可以运行,能展示这个问题:
import xml
from xml import sax
from xml.sax import handler
import traceback
class MyXMLHandler( handler.ContentHandler):
def __init__(self):
pass
def startElement(self, name, attrs):
for k in attrs.keys():
print 'type(k) = %s' % type(k)
if isinstance(k, (list, tuple)):
k = ''.join(k)
print 'type(k) = %s' % type(k)
print 'k = %s' % k
try:
print '%s = %s' % (k, attrs.getValue(k))
except Exception, e:
print '\nError:'
traceback.print_exc()
print ''
if __name__ == '__main__':
s = '<TAG A="0" AB="0" ABC="0"/>'
print '%s' % s
xml.sax.parseString(s, MyXMLHandler())
exit(0)
运行后,AB
这个属性会以元组的形式返回,而 A
和 ABC
这两个属性则是 Unicode 字符串,可以正常使用 get()
方法在 属性对象上操作。在我这里,Jython 2.5.2 的输出是:
> jython test.py
<TAG A="0" AB="0" ABC="0"/>
type(k) = <type 'unicode'>
type(k) = <type 'unicode'>
k = A
A = 0
type(k) = <type 'tuple'>
type(k) = <type 'unicode'>
k = AB
Error:
Traceback (most recent call last):
File "test.py", line 18, in startElement
print '%s = %s' % (k, attrs.getValue(k))
File "/usr/local/Cellar/jython/2.5.2/libexec/Lib/xml/sax/drivers2/drv_javasax.py", line 266, in getValue
value = self._attrs.getValue(_makeJavaNsTuple(name))
TypeError: getValue(): 1st arg can't be coerced to String, int
type(k) = <type 'unicode'>
type(k) = <type 'unicode'>
k = ABC
ABC = 0
这段代码在 OS X 上的 Python 2.7.2 和 CentOS 5.6 上的 Python 2.4.3 下运行正常。我查了一下 Jython 的 bug,但没找到类似的问题。
这是 Jython xml.sax 处理的已知问题吗?还是说我在我的处理程序中搞错了什么,导致与 2.5.2 不兼容?
补充:这似乎是 Jython 2.5.2 的一个 bug。我找到了一些相关的资料: http://sourceforge.net/mailarchive/message.php?msg_id=27783080 -- 欢迎提供解决方法的建议。
1 个回答
0
这是一个在Jython中报告的错误。我花了一些时间查找,最终在他们的错误档案中找到了它:
http://bugs.jython.org/issue1768
关于这个错误的第二条评论提供了一个解决方法:使用_attrs.getValue()
方法来获取属性列表中的值。像这样:
attrs._attrs.getValue('id')
我修改后的代码在我把这一行改成:
print '%s = %s' % (k, attrs.getValue(k))
后就可以正常工作了:
print '%s = %s' % (k, attrs._attrs.getValue(k))
一个更灵活的、在Python和Jython中都能用的解决方案是构建一个辅助函数:
def _attrsGetValue(attrs, name, default=None):
value = None
if 'jython' in sys.executable.lower():
value = attrs._attrs.getValue(name)
if not name:
value = default
else:
value = attrs.get(name, default)
return value