Почему анализатор xml.sax в Jython 2.5.2 превращает двухсимвольные атрибуты в кортежи? - PullRequest
0 голосов
/ 27 сентября 2011

Когда я сталкиваюсь с двухсимвольным атрибутом в своем XML-потоке при синтаксическом анализе с xml.sax в Jython 2.5.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() объекта Attribute . Под 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

Этот код работает правильно в Python 2.7.2 в OS X и Python 2.4.3 в CentOS 5.6. Я копался в ошибках Jython, но не смог найти ничего похожего на эту проблему.

Это известная проблема обработки Jython xml.sax? Или я что-то напутал в своем Handler, что несовместимо с 2.5.2?


Редактировать: похоже, это ошибка Jython 2.5.2. Я нашел ссылку на него: http://sourceforge.net/mailarchive/message.php?msg_id=27783080 - предложения для обхода приветствуются.

1 Ответ

0 голосов
/ 27 сентября 2011

Итак, это сообщаемая ошибка в 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))

Более гибкое решение works-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
...