2009-10-14 13 views
2

OK, les documents pour les liaisons libxml2 de Python sont vraiment ****. Mon problème:La libxml2 de Python ne peut pas analyser les chaînes Unicode

Un document XML est stocké dans une variable de chaîne en Python. La chaîne est une instance d'Unicode et contient des caractères non-ASCII. Je veux analyser avec libxml2, en regardant quelque chose comme ceci:

# -*- coding: utf-8 -*- 
import libxml2 

DOC = u"""<?xml version="1.0" encoding="UTF-8"?> 
<data> 
    <something>Bäääh!</something> 
</data> 
""" 

xml_doc = libxml2.parseDoc(DOC) 

avec ce résultat:

Traceback (most recent call last): 
    File "test.py", line 13, in <module> 
    xml_doc = libxml2.parseDoc(DOC) 
    File "c:\Python26\lib\site-packages\libxml2.py", line 1237, in parseDoc 
    ret = libxml2mod.xmlParseDoc(cur) 
UnicodeEncodeError: 'ascii' codec can't encode characters in position 46-48: 
ordinal not in range(128) 

Le point est la déclaration u"...". Si je le remplace par un simple "..", alors tout va bien. Malheureusement, cela ne fonctionne pas dans ma configuration, car DOC sera définitivement une instance Unicode.

Quelqu'un at-il une idée de la façon dont libxml2 peut être amené à analyser les chaînes codées en UTF-8?

+0

'u" ... "' est une ** chaîne unicode **, son codage interne n'est pas quelque chose qui vous intéresse, ce n'est pas UTF-8. – u0b34a0f6ae

+0

S'applique également à urrllib2, etc. –

Répondre

6

XML est un format binaire, en dépit de ressembler à un texte. Un encodage est spécifié au début du fichier XML afin de décoder les octets XML dans le texte.

Ce que vous devez faire est de passer str, pas unicode à votre bibliothèque:

xml_doc = libxml2.parseDoc(DOC.encode("UTF-8")) 

(Bien que quelques astuces sont possibles avec site.setencoding si vous êtes intéressé par la lecture ou l'écriture unicode chaînes avec conversion automatique via locale.)

Edit:The Unicode article par Joel Spolsky est bon guide pour les caractères de chaîne par rapport octets, codages, etc.

+0

Merci pour la réponse! OK, je suppose que je dois repenser aux chaînes en Python (bien que ce serait sympa de libxml2, si cela acceptait les instances de chaînes de base). – Boldewyn

9

Il devrait être

# -*- coding: utf-8 -*- 
import libxml2 

DOC = u"""<?xml version="1.0" encoding="UTF-8"?> 
<data> 
    <something>Bäääh!</something> 
</data> 
""".encode("UTF-8") 

xml_doc = libxml2.parseDoc(DOC) 

Le .encode ("UTF-8") est nécessaire pour obtenir la représentation binaire de la chaîne unicode avec l'encodage UTF8.

+0

Merci pour la réponse, cela fonctionne parfaitement. Andrey était le premier, cependant. – Boldewyn

Questions connexes