2014-05-08 5 views
3

Pour un projet, je suis supposé améliorer un fichier XML et le stocker dans un fichier. Le problème que je rencontrais est que je continue à obtenir l'erreur suivante:Erreur de codage/décodage d'ElementTree Unicode

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) 

Cette erreur a été générée par:

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

Lorsque vous cherchez une solution à ce problème que j'ai trouvé plusieurs suggestions disant que je devrais ajouter .decode('utf-8') à la fonction mais qui se traduit par une erreur de codage (d'abord il a été décodage) de la fonction d'écriture si cela ne fonctionne pas ...

l'erreur d'encodage:

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) 

Il est généré par le code suivant:

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

Source (ou au moins les parties concernées):

# 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) 

Et last but not least une URL à un échantillon XML: http://data.rechtspraak.nl/uitspraken/content?id=ECLI:NL:RVS:2012:BY1542

+0

Quelle est la trace complète de l'exception? Ce n'est pas ElementTree lui-même qui déclenche ça, je parierais. –

+0

Je viens d'ajouter les retraçages complets pour les deux exceptions :) – B8vrede

+0

Je ne peux pas reproduire le problème, pas avec Python 2.7.6 en tout cas. –

Répondre

5

L'exception est provoquée par une valeur de chaîne d'octet.

text dans le retraçage est censé être une valeur unicode, mais si elle est une chaîne d'octets ordinaire, Python va d'abord implicitement le décoder (avec le codec ASCII) à Unicode juste pour que vous pouvez alors encode à nouveau.

C'est que décodant qui échoue. Parce que vous ne nous avez pas réellement montré ce que vous insérez dans l'arborescence XML, il est difficile de vous dire quoi corriger, sauf pour vous assurer que vous utilisez toujours des valeurs Unicode lors de l'insertion de texte.

Démo:

>>> 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\'?> ...' 

Définition d'un attribut bytestring, contenant octets en dehors de la plage ASCII, déclenche la excetpion; l'utilisation d'une valeur unicode garantissait plutôt que le résultat pouvait être produit.