2013-06-16 28 views
5

Tôi đang cố gắng gán một chuỗi văn bản Pháp hợp lệ để một chuỗi văn bản sử dụng lxml:Pháp và lxml văn bản

el = etree.Element("someelement") 
el.text = 'Disponible à partir du 1er Octobre' 

tôi nhận được lỗi:

ValueError: All strings must be XML compatible: Unicode or ASCII, no NULL bytes or control characters

Tôi cũng đã thử:

el.ext = etree.CDATA('Disponible à partir du 1er Octobre') 

Tuy nhiên tôi cũng gặp lỗi tương tự.

Làm cách nào để xử lý tiếng Pháp trong XML, cụ thể là ISO-8859-1? Có nhiều cách để chỉ định mã hóa trong hàm tostring() trong lxml, nhưng không phải để gán giá trị văn bản trong các phần tử.

+0

el.text = etree.CDATA (('Disponible à partir du 1er Octobre'). Decode ('utf-8')) hoặc el.text = ('Disponible à partir du 1er Octobre'). Decode (' utf-8 ') – shiva

Trả lời

3

Nếu văn bản chứa dữ liệu không ascii thì bạn nên cung cấp cho nó như là một chuỗi Unicode cho el.text.

@Abbasov Alexander's answer cho thấy bạn có thể làm điều đó bằng cách sử dụng mã Unicode u''. Python đã không đưa ra một ngoại lệ vì vậy tôi giả định rằng bạn đã khai báo một mã hóa ký tự của tệp nguồn Python của bạn (ví dụ: sử dụng # coding: utf-8 nhận xét ở trên cùng). Mã hóa này xác định cách Python diễn giải các ký tự không phải ascii trong nguồn, nó không liên quan đến mã hóa bạn sử dụng để lưu xml vào một tệp.

Nếu văn bản đã có trong một biến và bạn chưa chuyển đổi nó thành Unicode, bạn có thể làm điều đó bằng cách sử dụng text.decode(text_encoding) (text_encoding có thể không liên quan đến mã hóa nguồn Python).

Bit khó hiểu có thể là el.text (dưới dạng tối ưu hóa) trả về giá trị tối ưu trên Python 2 cho dữ liệu ascii thuần túy. Nó phá vỡ quy tắc mà bạn không nên trộn các chuỗi byte và Unicode. Mặc dù nó sẽ hoạt động nếu sys.getdefaultencoding() trả về mã hóa dựa trên ascii như trong hầu hết các trường hợp.

Để lưu xml, vượt qua bất kỳ ký tự mã hóa, bạn cần phải tostring() hoặc ElementTree.write() chức năng. Một lần nữa, mã hóa này không liên quan đến những người khác đã được đề cập mã hóa. Thông thường, sử dụng Unicode sandwich: giải mã byte thành Unicode ngay sau khi bạn nhận được chúng, làm việc với văn bản Unicode bên trong chương trình của bạn, mã hóa thành byte càng muộn càng tốt khi bạn cần gửi văn bản bằng API không hỗ trợ Unicode (tệp, mạng).

+0

Không phải là một thông báo lỗi hơi khó hiểu? Người dùng thực sự cung cấp Unicode UTF-8 và nó nói nó phải là Unicode hoặc Ascii. Tôi nghĩ rằng nó sẽ được rõ ràng hơn nếu nó nói - Đầu vào phải được loại 'unicode' hoặc 'str' với ký tự ascii (hoặc không có ký tự không ascii). – Nishant

+1

@Nantant: Tôi đồng ý. Bạn có thể đề xuất một từ ngữ tốt hơn trên trình theo dõi vấn đề của lxml. Mặc dù, trên Python 3, nó là 'str' và' byte' tương ứng. Nếu nó không rõ ràng từ câu trả lời; khuyến nghị của tôi: luôn sử dụng Unicode ('unicode' trên Python 2,' str' trên Python 3), để biểu diễn văn bản. Không sử dụng tối ưu hóa 'byte' khó hiểu cho văn bản ASCII. Dù sao, trong các phiên bản Python gần đây, chuỗi Unicode chỉ chứa ascii không tiêu thụ nhiều bộ nhớ hơn (do biểu diễn linh hoạt của chuỗi Unicode trong Python 3.3+), nghĩa là tối ưu hóa thậm chí còn ít ý nghĩa hơn. – jfs

5

Nếu bạn có phiên bản của python < 3 bạn có thể thử: el.text = u'Disponible à partir du 1er Octobre'

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