2013-05-12 39 views
32

Tôi đang tạo tệp XML bằng Python và có một trường trên XML của tôi mà tôi đặt nội dung của tệp văn bản. Tôi làm điều đó bằng cáchUnicodeDecodeError: 'ascii' codec không thể giải mã byte 0xc2

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

Và sau đó tôi nhận được UnicodeDecodeError. Tôi đã cố gắng để đưa các bình luận đặc biệt # -*- coding: utf-8 -*- trên đầu trang của kịch bản của tôi nhưng vẫn có lỗi. Ngoài ra tôi đã cố gắng để thực thi mã hóa của biến của tôi data.encode('utf-8') nhưng vẫn có lỗi. Tôi biết vấn đề này là rất phổ biến nhưng tất cả các giải pháp tôi nhận được từ các câu hỏi khác đã không làm việc cho tôi.

CẬP NHẬT

Traceback: Chỉ sử dụng những nhận xét đặc biệt trên dòng đầu tiên của kịch bản

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: Sử dụng .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) 

tôi đã sử dụng .decode('utf-8') và thông báo lỗi đã không xuất hiện và nó đã tạo thành công tệp XML của tôi. Nhưng vấn đề là XML không thể xem được trên trình duyệt của tôi.

+1

Sẽ hữu ích khi xem toàn bộ thông báo lỗi để xem thông báo lỗi đến từ đâu. Trong khi chờ đợi, hãy thử sử dụng 'decode' thay vì' encode'. –

+0

Đã cập nhật, nó đã tạo thành công XML của tôi khi tôi sử dụng 'giải mã', nhưng tệp không thể xem được trên trình duyệt của tôi. –

+2

Lưu ý rằng việc sử dụng '# - * - coding: utf-8 - * -' chỉ dùng để chèn các ký tự không phải ASCII vào các nguồn python. Nó không ảnh hưởng đến mã hóa/giải mã các chuỗi theo bất kỳ cách nào. Ngoài ra, nếu tệp 'myText.txt' không phải ASCII, bạn nên sử dụng' codecs.open' và cung cấp mã hóa đúng: 'codecs.open ('myText.txt', 'r', 'utf-8')' . – Bakuriu

Trả lời

56

Bạn cần giải mã dữ liệu từ chuỗi đầu vào thành unicode, trước khi sử dụng, để tránh các sự cố mã hóa.

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

Tôi đã gặp lỗi tương tự trong pywikipediabot. Phương pháp .decode là một bước đi đúng hướng nhưng đối với tôi nó đã không làm việc mà không cần thêm 'ignore':

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

Lưu ý rằng bỏ qua các lỗi mã hóa sẽ có khả năng mất dữ liệu hoặc tạo ra kết quả không chính xác. – tripleee

6

Python 2

Các lỗi được gây ra bởi vì ElementTree không mong đợi để tìm phi Các chuỗi ASCII đặt XML khi cố gắng viết nó ra. Bạn nên sử dụng chuỗi Unicode cho phi ASCII để thay thế. Có thể tạo chuỗi Unicode bằng cách sử dụng tiền tố u trên các chuỗi, ví dụ: u'€' hoặc bằng cách giải mã chuỗi bằng mystr.decode('utf-8') bằng cách sử dụng mã hóa thích hợp.

Cách tốt nhất là giải mã tất cả dữ liệu văn bản khi đọc, thay vì giải mã giữa chương trình. Mô-đun io cung cấp phương thức open() giải mã dữ liệu văn bản thành chuỗi Unicode khi được đọc.

ElementTree sẽ vui hơn nhiều với Unicodes và mã hóa chính xác nó khi sử dụng phương pháp ET.write().

Ngoài ra, để có khả năng tương thích và dễ đọc tốt nhất, hãy đảm bảo rằng ET mã hóa thành UTF-8 trong thời gian write() và thêm tiêu đề có liên quan.

Giả sử tập tin đầu vào của bạn là UTF-8 mã hóa (0xC2 thường UTF-8 dẫn byte), đặt tất cả mọi thứ cùng nhau, và sử dụng câu lệnh with, mã của bạn sẽ giống như thế:

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) 

Output:

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

#!/usr/bin/python

# encoding=utf8

Hãy thử Điều này để bắt đầu tệp python

Các vấn đề liên quan