web-dev-qa-db-fra.com

ElementTree et unicode

J'ai ce caractère dans un fichier xml:

<data>
  <products>
      <color>fumè</color>
  </product>
</data>

J'essaye de générer une instance d'ElementTree avec le code suivant:

string_data = open('file.xml')
x = ElementTree.fromstring(unicode(string_data.encode('utf-8')))

et j'obtiens l'erreur suivante:

UnicodeEncodeError: 'ascii' codec can't encode character u'\xe8' in position 185: ordinal not in range(128)

(REMARQUE: la position n'est pas exacte, j'ai échantillonné le xml à partir d'un plus grand).

Comment le résoudre? Merci

20
pistacchio

Vous n'avez pas besoin de décoder XML pour que ElementTree fonctionne. XML porte ses propres informations d'encodage (par défaut UTF-8) et ElementTree fait le travail pour vous, en produisant unicode:

>>> data = '''\
... <data>
...   <products>
...       <color>fumè</color>
...   </products>
... </data>
... '''
>>> x = ElementTree.fromstring(data)
>>> x[0][0].text
u'fum\xe8'

Si vos données sont contenues dans un objet fichier (comme), transmettez simplement le nom de fichier ou l'objet fichier directement à la fonction ElementTree.parse():

x = ElementTree.parse('file.xml')
10
Martijn Pieters

Vous pourriez être tombé sur ce problème en utilisant Requests (HTTP for Humans) , response.text décode la réponse par défaut, vous pouvez utiliser response.content pour obtenir les données non décodées, afin que ElementTree puisse les décoder lui-même. N'oubliez pas d'utiliser le bon encodage.

Plus d'infos: http://docs.python-requests.org/en/latest/user/quickstart/#response-content

32
gitaarik

Vous devez décoder les chaînes utf-8 en un objet Unicode. Alors

string_data.encode('utf-8')

devrait être

string_data.decode('utf-8')

en supposant string_data est en fait une chaîne utf-8.

Donc pour résumer: pour obtenir une chaîne utf-8 à partir d'un objet unicode, vous encodez l'unicode (en utilisant l'encodage utf-8), et chaîne en un objet Unicode que vous décodez la chaîne en utilisant le codage respectif.

Pour plus de détails sur les concepts que je suggère de lire Le minimum absolu que tout développeur de logiciel doit absolument, positivement savoir sur Unicode et les jeux de caractères (pas Python spécifique)).

14
Lukas Graf

Avez-vous essayé d'utiliser la fonction parse, au lieu d'ouvrir le fichier ... (ce qui nécessiterait un .read() après pour que la .fromstring() fonctionne ... )

import xml.etree.ElementTree as ET

tree = ET.parse('file.xml')
root = tree.getroot()
# etc...
3
Jon Clements

La fonction open() ne renvoie pas de string. Utilisez plutôt open('file.xml').read().

1
hejhula

Le plus probable, votre fichier n'est pas UTF-8. Le caractère è Peut provenir d'un autre codage, latin-1 Par exemple.

0
Maksym Polshcha