在Jython 2.5.2下使用xml.sax解析时,我在XML流中遇到2个字符的属性,它会将属性名称转换为元组。没有任何强制的名称允许我提取属性的值。我尝试传递元组或将其转换为字符串并传递它。两种情况都会导致:
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()
方法上正常运行3}}。在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处理问题吗?或者我在Handler中弄乱了2.5.2不兼容的东西?
编辑:这似乎是一个Jython 2.5.2错误。我找到了对它的引用:Attribute object - 有关变通方法欢迎的建议。
答案 0 :(得分:0)
所以,这是Jython中报告的错误。这需要一些挖掘,但我在他们的bug存档中找到了它:
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))
更灵活的work-in-python-and-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