2013-05-12 12 views
32

Ich erstelle XML-Datei in Python und es gibt ein Feld auf meinem XML, das ich den Inhalt einer Textdatei einfüge. Ich mache es durchUnicodeDecodeError: 'Ascii' Codec kann Byte 0xc2 nicht decodieren

f = open ('myText.txt',"r") 
data = f.read() 
f.close() 

root = ET.Element("add") 
doc = ET.SubElement(root, "doc") 

field = ET.SubElement(doc, "field") 
field.set("name", "text") 
field.text = data 

tree = ET.ElementTree(root) 
tree.write("output.xml") 

Und dann bekomme ich die UnicodeDecodeError. Ich habe bereits versucht, den speziellen Kommentar # -*- coding: utf-8 -*- oben auf meinem Skript zu setzen, aber immer noch den Fehler. Ich habe auch versucht, die Codierung meiner Variablen data.encode('utf-8') zu erzwingen, aber immer noch den Fehler. Ich weiß, dass dieses Problem sehr häufig ist, aber alle Lösungen, die ich von anderen Fragen bekam, funktionierten nicht für mich.

UPDATE

Traceback: nur die speziellen Kommentar Verwendung in der ersten Zeile des Skripts

Traceback (most recent call last): 
    File "D:\Python\lse\createxml.py", line 151, in <module> 
    tree.write("D:\\python\\lse\\xmls\\" + items[ctr][0] + ".xml") 
    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 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 0xc2 in position 243: ordina 
l not in range(128) 

Traceback: Mit .encode('utf-8')

Traceback (most recent call last): 
    File "D:\Python\lse\createxml.py", line 148, in <module> 
    field.text = data.encode('utf-8') 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 227: ordina 
l not in range(128) 

I .decode('utf-8') und die Fehlermeldung verwendet erschien nicht und es hat erfolgreich meine XML-Datei erstellt. Aber das Problem ist, dass das XML in meinem Browser nicht sichtbar ist.

+1

Es wäre nützlich, die gesamte Fehlermeldung zu sehen, wo es herkommt. Versuchen Sie in der Zwischenzeit, 'decode' anstelle von' encode' zu ​​verwenden. –

+0

Aktualisiert, es hat erfolgreich mein XML erstellt, wenn ich 'decode' verwende, aber die Datei ist in meinem Browser nicht sichtbar. –

+2

Beachten Sie, dass die Verwendung von '# - * - coding: utf-8 - * -' nur dazu dient, Nicht-ASCII-Zeichen in die Python-Quellen einzufügen. Es hat keinerlei Auswirkungen auf die Kodierung/Dekodierung von Strings. Wenn die Datei 'myText.txt' nicht ASCII ist, sollten Sie' codecs.open' verwenden und die richtige Kodierung angeben: 'codecs.open ('myText.txt', 'r', 'utf-8')' . – Bakuriu

Antwort

56

Sie müssen Daten aus der Eingabezeichenfolge in Unicode dekodieren, bevor Sie sie verwenden, um Codierungsprobleme zu vermeiden.

field.text = data.decode("utf8") 
12

Ich geriet in einen ähnlichen Fehler in pywikipedia. Die .decode Verfahren ist ein Schritt in die richtige Richtung, aber für mich ist es nicht 'ignore' ohne Zugabe nicht funktioniert:

fix_encoding = lambda s: s.decode('utf8', 'ignore') 
+10

Beachten Sie, dass das Ignorieren von Codierungsfehlern möglicherweise Daten verlieren wird , oder produzieren falsche Ausgabe. – tripleee

6

Python 2

Der Fehler wird verursacht, weil ElementTree nicht erwarten, nicht zu finden ASCII-Zeichenfolgen setzen das XML beim Versuch, es auszugeben. Sie sollten stattdessen Unicode-Zeichenfolgen für Nicht-ASCII verwenden. Unicode-Zeichenfolgen können entweder unter Verwendung des Präfix u für Zeichenfolgen, d. H. u'€', oder durch Decodieren einer Zeichenfolge mit mystr.decode('utf-8') unter Verwendung der entsprechenden Codierung erstellt werden.

Die beste Vorgehensweise besteht darin, alle Textdaten beim Lesen zu dekodieren, anstatt sie mitten im Programm zu dekodieren. Das io-Modul stellt eine open()-Methode bereit, die Textdaten in Unicode-Zeichenfolgen decodiert, während sie gelesen werden.

ElementTree wird viel glücklicher mit Unicodes sein und wird es korrekt codieren, wenn es die Methode ET.write() verwendet.

Um eine optimale Kompatibilität und Lesbarkeit zu gewährleisten, stellen Sie außerdem sicher, dass ET während write() in UTF-8 codiert und den entsprechenden Header hinzufügt.

Ihre Eingabedatei ist UTF-8 kodierten Vorausgesetzt (0xC2 gemeinsame UTF-8-Lead Byte ist), alles zusammen setzen, und mit Hilfe der with Anweisung, sollte Ihr Code wie folgt aussehen:

with io.open('myText.txt', "r", encoding='utf-8') as f: 
    data = f.read() 

root = ET.Element("add") 
doc = ET.SubElement(root, "doc") 

field = ET.SubElement(doc, "field") 
field.set("name", "text") 
field.text = data 

tree = ET.ElementTree(root) 
tree.write("output.xml", encoding='utf-8', xml_declaration=True) 

Ausgang:

<?xml version='1.0' encoding='utf-8'?> 
<add><doc><field name="text">data€</field></doc></add> 
3

#!/usr/bin/python

# encoding=utf8

Versuchen Sie dies zu Beginn der Python-Datei

Verwandte Themen