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>�</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
là �
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ố �
thành một byte null không hợp lệ. :-)
cleaned_s = StringIO(
BeautifulStoneSoup('<test><null>�</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]
.
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
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. –
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