2010-06-14 19 views
5

Tôi đã viết một hàm nhỏ, trong đó sử dụng ElementTree và xpath để trích xuất nội dung văn bản của một số yếu tố trong một tập tin xml:Python + Expat: Lỗi trên � thực thể

#!/usr/bin/env python2.5 

import doctest 
from xml.etree import ElementTree 
from StringIO import StringIO 

def parse_xml_etree(sin, xpath): 
    """ 
Takes as input a stream containing XML and an XPath expression. 
Applies the XPath expression to the XML and returns a generator 
yielding the text contents of each element returned. 

>>> parse_xml_etree(
... StringIO('<test><elem1>one</elem1><elem2>two</elem2></test>'), 
... '//elem1').next() 
'one' 
>>> parse_xml_etree(
... StringIO('<test><elem1>one</elem1><elem2>two</elem2></test>'), 
... '//elem2').next() 
'two' 
>>> parse_xml_etree(
... StringIO('<test><null>&#0;</null><elem3>three</elem3></test>'), 
... '//elem2').next() 
'three' 
""" 

    tree = ElementTree.parse(sin) 
    for element in tree.findall(xpath): 
    yield element.text 

if __name__ == '__main__': 
    doctest.testmod(verbose=True) 

Các thử nghiệm thứ ba không thành công với những điều sau đây ngoại lệ:

ExpatError: tham chiếu đến số không hợp lệ nhân vật: dòng 1, cột 13

&#0; thực thể XML bất hợp pháp? Bất kể nó có hay không, các tập tin tôi muốn phân tích chứa nó, và tôi cần một số cách để phân tích chúng. Bất kỳ đề xuất nào cho một trình phân tích cú pháp khác ngoài Expat, hoặc các thiết lập cho Expat, điều đó sẽ cho phép tôi làm điều đó?


Cập nhật: Tôi phát hiện BeautifulSoup ngay bây giờ, một phân tích cú pháp súp tag như đã nêu dưới đây trong các bình luận câu trả lời, và để cho vui Tôi quay trở lại với vấn đề này và cố gắng sử dụng nó như là một XML-sạch trước ElementTree , nhưng nó đã chuyển đổi một cách tỉ mỉ số &#0; thành một byte null không hợp lệ. :-)

cleaned_s = StringIO(
    BeautifulStoneSoup('<test><null>&#0;</null><elem3>three</elem3></test>', 
        convertEntities=BeautifulStoneSoup.XML_ENTITIES 
).renderContents() 
) 
tree = ElementTree.parse(cleaned_s) 

... sản lượng

xml.parsers.expat.ExpatError: not well-formed (invalid token): line 1, column 12 

Trong trường hợp đặc biệt của tôi, mặc dù tôi đã không thực sự cần phân tích XPath như vậy, tôi có thể đã đi với chính nó BeautifulSoup và nó khá đơn giản kiểu địa chỉ nút parsed_tree.test.elem1.contents[0].

Trả lời

6

&#0; không nằm trong số legal character range được xác định bởi thông số XML. Than ôi, kỹ năng Python của tôi khá thô sơ, vì vậy tôi không giúp được gì nhiều.

+0

Hm, vâng, đặc điểm kỹ thuật làm cho nó khá rõ ràng. Cảm ơn bạn đã tham khảo chính xác. – clacke

+0

Tôi nhận ra đây là một chuỗi cũ, nhưng thông số cho biết ký tự * chữ * chỉ có thể xuất hiện trong XML. Chuỗi byte � không phải là * theo nghĩa đen * một ký tự rỗng, nhưng chuỗi gồm 4 ký tự * đại diện cho * một byte rỗng. Với sự khác biệt đó, có phải là � hợp pháp không? Tôi không thể tìm thấy bất cứ điều gì trong spec nói * rằng * là bất hợp pháp. –

+1

Câu hỏi hợp lệ. Nhưng câu trả lời là ở đây: http://www.w3.org/TR/REC-xml/#sec-references cho biết "Ký tự được đề cập đến bằng cách sử dụng các tham chiếu ký tự PHẢI khớp với sản phẩm cho Char." – clacke

4

&#0; không phải là ký tự XML hợp lệ. Lý tưởng nhất, bạn có thể làm cho người tạo tệp để thay đổi quy trình của họ để tệp không hợp lệ như thế này.

Nếu bạn phải chấp nhận các tệp này, bạn có thể xử lý trước chúng để biến &#0 thành nội dung khác. Ví dụ: chọn @ làm ký tự thoát, chuyển "@" thành "@@" và "&#0;" thành "@ 0".

Khi bạn nhận được dữ liệu văn bản từ trình phân tích cú pháp, bạn có thể đảo ngược ánh xạ. Đây chỉ là một ví dụ, bạn có thể phát minh ra bất kỳ cú pháp thoát nào mà bạn thích.

+0

Trong trường hợp cụ thể của tôi, tôi chỉ có thể xóa chúng. Chúng nằm trong một phần tử không liên quan của XML. Cảm thấy run rẩy để sử dụng xử lý văn bản để xử lý XML mặc dù, nhưng kể từ khi nó không được hình thành tốt, tôi đoán tôi không có sự lựa chọn ... Sử dụng một số loại phân tích cú pháp súp thẻ có vẻ quá mức cần thiết. – clacke

+0

Bạn có chắc chắn rằng thuật toán thoát là mạnh mẽ không? Bạn không phải xem xét ưu tiên của các tính năng trong ngữ pháp của XML? –

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