2012-04-06 6 views
9

Sto cercando di scrivere un file XML con dati UTF-8 codificati utilizzando ElementTree come questo:scrittura di file XML UTF-8 con dati UTF-8 con ElementTree

#!/usr/bin/python                  
# -*- coding: utf-8 -*-                 

import xml.etree.ElementTree as ET 
import codecs 

testtag = ET.Element('unicodetag') 
testtag.text = u'Töreboda' #The o is really ö (o with two dots over). No idea why SO dont display this 
expfile = codecs.open('testunicode.xml',"w","utf-8-sig") 
ET.ElementTree(testtag).write(expfile,encoding="UTF-8",xml_declaration=True) 
expfile.close() 

Questo colpi con l'errore

Traceback (most recent call last): 
    File "unicodetest.py", line 10, in <module> 
    ET.ElementTree(testtag).write(expfile,encoding="UTF-8",xml_declaration=True) 
    File "/usr/lib/python2.7/xml/etree/ElementTree.py", line 815, in write 
    serialize(write, self._root, encoding, qnames, namespaces)  
    File "/usr/lib/python2.7/xml/etree/ElementTree.py", line 932, in _serialize_xml 
    write(_escape_cdata(text, encoding)) 
    File "/usr/lib/python2.7/codecs.py", line 691, in write 
    return self.writer.write(data) 
    File "/usr/lib/python2.7/codecs.py", line 351, in write 
    data, consumed = self.encode(object, self.errors) 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 1: ordinal not in range(128) 

L'utilizzo della codifica "us-ascii" funziona bene, ma non conserva i caratteri unicode nei dati. Che cosa sta succedendo?

risposta

17

codecs.open prevede che le stringhe Unicode vengano scritte sull'oggetto file e gestirà la codifica in UTF-8. Il codice write di ElementTree codifica le stringhe Unicode in stringhe di byte UTF-8 prima di inviarle all'oggetto file. Poiché l'oggetto file richiede stringhe Unicode, sta forzando la stringa di byte su Unicode utilizzando il codec ascii predefinito e causando lo UnicodeDecodeError.

solo fare questo:

#expfile = codecs.open('testunicode.xml',"w","utf-8-sig") 
ET.ElementTree(testtag).write('testunicode.xml',encoding="UTF-8",xml_declaration=True) 
#expfile.close() 
+2

+1. Giusto per chiarire questo: il problema è che stai cercando di codificare unicode-> utf-8 due volte: ElementTree lo fa una volta, e poi il flusso abilitato per il codec prova a farlo di nuovo. Ma questo secondo passaggio viene confuso poiché il suo input è già codificato (si aspetta una stringa unicode, ma ottiene invece una stringa di byte codificata utf-8). –

+0

Qui mi dedico a pensare che sto aiutando fornendo un file Unicode ... Posso solo dire che AMO StackOverflow? Una risposta perfetta entro 3 ore! Anche l'elaborazione dei segni sta spiegando molto. – c0m4

+1

Ho avuto a che fare con dati utf-8 e ho ricevuto errori simili in ElementTree._serialize_text() o _serialize_xml() quando si tenta di scrivere su un file xml. Sono stato in grado di risolverlo convertendo le mie stringhe in unicode usando myString.decode ('utf-8') prima di aggiungerle al mio oggetto ET.Element. Sembra che ET.ElementTree.write() non sia felice con altre codifiche di stringhe. – drevicko