2014-05-08 4 views
3

Для проекта я должен улучшить некоторые XML и сохранить его в файле. Проблема я столкнулся в том, что я получаю следующее сообщение об ошибке:ElementTree Unicode Encode/Decode Error

Traceback (most recent call last): 
    File "C:\Python27\lib\multiprocessing\process.py", line 258, in _bootstrap 
    self.run() 
    File "C:\Python27\lib\multiprocessing\process.py", line 114, in run 
    self._target(*self._args, **self._kwargs) 
    File "C:\Users\Bart\Dropbox\Studie\2013-2014\BSc-KI\cite_parser\parser.py", line 193, in parse_references 
    outputXML = ET.tostring(root, encoding='utf8', method='xml') 
    File "C:\Python27\lib\xml\etree\ElementTree.py", line 1126, in tostring 
    ElementTree(element).write(file, encoding, method=method) 
    File "C:\Python27\lib\xml\etree\ElementTree.py", line 820, in write 
    serialize(write, self._root, encoding, qnames, namespaces) 
    File "C:\Python27\lib\xml\etree\ElementTree.py", line 939, in _serialize_xml 
    _serialize_xml(write, e, encoding, qnames, None) 
    File "C:\Python27\lib\xml\etree\ElementTree.py", line 939, in _serialize_xml 
    _serialize_xml(write, e, encoding, qnames, None) 
    File "C:\Python27\lib\xml\etree\ElementTree.py", line 939, in _serialize_xml 
    _serialize_xml(write, e, encoding, qnames, None) 
ECLI:NL:RVS:2012:BY1564 
File "C:\Python27\lib\xml\etree\ElementTree.py", line 937, in _serialize_xml 
    write(_escape_cdata(text, encoding)) 
    File "C:\Python27\lib\xml\etree\ElementTree.py", line 1073, in _escape_cdata 
    return text.encode(encoding, "xmlcharrefreplace") 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 80: ordinal not in range(128) 

Эта ошибка была порожденную:

outputXML = ET.tostring(root, encoding='utf8', method='xml') 

При поиске решения этой проблемы я нашел несколько предложений, говоря, что я должен добавить .decode('utf-8') к функции, но это приводит к ошибке кодирования (сначала он был декодирования) от функции записи так, что не работает ...

ошибка кодирования:

Traceback (most recent call last): 
    File "C:\Python27\lib\multiprocessing\process.py", line 258, in _bootstrap 
    self.run() 
    File "C:\Python27\lib\multiprocessing\process.py", line 114, in run 
    self._target(*self._args, **self._kwargs) 
    File "C:\Users\Bart\Dropbox\Studie\2013-2014\BSc-KI\cite_parser\parser.py", line 197, in parse_references 
    myfile.write(outputXML) 
UnicodeEncodeError: 'ascii' codec can't encode character u'\xeb' in position 13559: ordinal not in range(128) 

Оно генерируется следующим кодом:

outputXML = ET.tostring(root, encoding='utf8', method='xml').decode('utf-8') 

Источник (или, по крайней мере, соответствующие части):

# URL encodes the parameters 
encoded_parameters = urllib.urlencode({'id':ecli}) 

# Opens XML file 
feed = urllib2.urlopen("http://data.rechtspraak.nl/uitspraken/content?"+encoded_parameters, timeout = 3) 

# Parses the XML 
ecliFile = ET.parse(feed) 

# Fetches root element of current tree 
root = ecliFile.getroot() 

# Write the XML to a file without any extra indents or newlines 
outputXML = ET.tostring(root, encoding='utf8', method='xml') 

# Write the XML to the file 
with open(file, "w") as myfile: 
    myfile.write(outputXML) 

И последнее, но не в последнюю очередь URL для образца XML: http://data.rechtspraak.nl/uitspraken/content?id=ECLI:NL:RVS:2012:BY1542

+0

Какова полная трассировка исключения? Это не сам ElementTree, который вызывает это, я бы сделал ставку. –

+0

Я только что добавил полные трассировки для обоих исключений :) – B8vrede

+0

Я не могу воспроизвести проблему, а не с Python 2.7.6 во всяком случае. –

ответ

5

Исключение вызвано значением строки байта.

text в TRACEBACK должно быть значение Юникода, но если это простая строка байт, Python неявно первым декодировать (с ASCII-кодеком) в Unicode только так вы можете затем закодировать его снова.

Это декодирование, что не удается.

Поскольку вы фактически не показывали нам, что вы вставляете в дерево XML, трудно сказать, что исправить, кроме того, чтобы всегда использовать значения Unicode при вставке текста.

Демо:

>>> root.attrib['oops'] = u'Data with non-ASCII codepoints \u2014 (em dash)'.encode('utf8') 
>>> ET.tostring(root, encoding='utf8', method='xml') 
Traceback (most recent call last): 
    File "<console>", line 1, in <module> 
    File "/Users/mj/Development/Library/buildout.python/parts/opt/lib/python2.7/xml/etree/ElementTree.py", line 1126, in tostring 
    ElementTree(element).write(file, encoding, method=method) 
    File "/Users/mj/Development/Library/buildout.python/parts/opt/lib/python2.7/xml/etree/ElementTree.py", line 820, in write 
    serialize(write, self._root, encoding, qnames, namespaces) 
    File "/Users/mj/Development/Library/buildout.python/parts/opt/lib/python2.7/xml/etree/ElementTree.py", line 932, in _serialize_xml 
    v = _escape_attrib(v, encoding) 
    File "/Users/mj/Development/Library/buildout.python/parts/opt/lib/python2.7/xml/etree/ElementTree.py", line 1090, in _escape_attrib 
    return text.encode(encoding, "xmlcharrefreplace") 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 31: ordinal not in range(128) 
>>> root.attrib['oops'] = u'Data with non-ASCII codepoints \u2014 (em dash)' 
>>> ET.tostring(root, encoding='utf8', method='xml') 
'<?xml version=\'1.0\' encoding=\'utf8\'?> ...' 

Установка атрибута байтовой строки, содержащий байты за пределами диапазона ASCII, вызывает excetpion; использование значения unicode вместо этого обеспечило бы получение результата.