Xử lý XML bằng Python [đã đóng]


77

Tôi sắp xây dựng một phần của dự án sẽ cần phải xây dựng và đăng một tài liệu XML lên một dịch vụ web và tôi muốn làm điều đó bằng Python, như một phương tiện để mở rộng kỹ năng của tôi trong đó.

Thật không may, mặc dù tôi biết khá rõ về mô hình XML trong .NET, nhưng tôi không chắc những ưu và nhược điểm của các mô hình XML trong Python.

Có ai có kinh nghiệm xử lý XML bằng Python không? Bạn sẽ đề nghị tôi bắt đầu từ đâu? Các tệp XML mà tôi sẽ xây dựng sẽ khá đơn giản.


Dive Into Python có một chương. Không thể đảm bảo nó sẽ tốt như thế nào.
Bernard

4
Đầu tiên python câu hỏi
Roshan

Câu trả lời:


31

Cá nhân tôi đã thử với một số tùy chọn tích hợp trong một dự án nặng về XML và đã giải quyết pulldom như là lựa chọn tốt nhất cho các tài liệu ít phức tạp hơn.

Đặc biệt đối với những thứ đơn giản nhỏ, tôi thích lý thuyết phân tích cú pháp theo hướng sự kiện hơn là thiết lập một loạt các lệnh gọi lại cho một cấu trúc tương đối đơn giản. Dưới đây là một cuộc thảo luận nhanh về cách sử dụng API .

Điều tôi thích: bạn có thể xử lý phân tích cú pháp trong một forvòng lặp hơn là sử dụng các lệnh gọi lại. Bạn cũng trì hoãn việc phân tích cú pháp đầy đủ (phần "kéo") và chỉ nhận được chi tiết bổ sung khi bạn gọi expandNode(). Điều này đáp ứng yêu cầu chung của tôi về hiệu quả "có trách nhiệm" mà không phải hy sinh tính dễ sử dụng và đơn giản.


Không phải pulldom là một công cụ để phân tích cú pháp XML, không tạo ra nó (đó là những gì câu hỏi đặt ra)?
cunkel 20/09/08

31

ElementTree có một API pythony đẹp. Tôi nghĩ nó thậm chí còn được vận chuyển như một phần của python 2.5

Nó ở dạng python thuần túy và như tôi đã nói, khá hay, nhưng nếu bạn cần nhiều hiệu suất hơn, thì lxml sẽ hiển thị cùng một API và sử dụng libxml2. Về mặt lý thuyết, bạn có thể chỉ cần hoán đổi nó khi bạn thấy mình cần.


1
Để hoàn thành câu trả lời của mình, bạn có thể thêm rằng lxml cũng hỗ trợ lược đồ XML và XPath không được ElementTree hỗ trợ không? Và nó thực sự được vận chuyển với Python 2.5.
Torsten Marek

2
ElementTree tốt cho đến khi bạn cần xử lý không gian tên sau đó nó bị hỏng và không sử dụng được.
Ryu

6

Nói chung, có 3 cách chính để xử lý XML: dom, sax và xpath. Mô hình dom là tốt nếu bạn có đủ khả năng tải toàn bộ tệp xml của mình vào bộ nhớ cùng một lúc và bạn không ngại xử lý các cấu trúc dữ liệu và bạn đang xem xét phần lớn / phần lớn mô hình. Mô hình sax là tuyệt vời nếu bạn chỉ quan tâm đến một vài thẻ và / hoặc bạn đang xử lý các tệp lớn và có thể xử lý chúng theo tuần tự. Mỗi mô hình xpath là một chút - bạn có thể chọn và chọn đường dẫn đến các phần tử dữ liệu bạn cần, nhưng nó yêu cầu nhiều thư viện hơn để sử dụng.

Nếu bạn muốn đơn giản và được đóng gói bằng Python, minidom là câu trả lời của bạn, nhưng nó khá khập khiễng và tài liệu là "đây là tài liệu về dom, hãy tìm hiểu". Nó thực sự phiền phức.

Cá nhân tôi thích cElementTree, là một triển khai nhanh hơn (dựa trên c) của ElementTree, là một mô hình giống như dom.

Tôi đã sử dụng các hệ thống sax, và theo nhiều cách, chúng có vẻ "giống con trăn" hơn, nhưng tôi thường kết thúc việc tạo ra các hệ thống dựa trên trạng thái để xử lý chúng và theo cách đó là sự điên rồ (và lỗi).

Tôi nói rằng hãy sử dụng minidom nếu bạn thích nghiên cứu, hoặc ElementTree nếu bạn muốn mã tốt hoạt động tốt.


Trong Python, có những người khác cách, chẳng hạn như ElementTree (xem trả lời Gareth Simpson)
bortzmeyer

6

Tôi đã sử dụng ElementTree cho một số dự án và giới thiệu nó.

Nó là pythonic, đi kèm 'trong hộp' với Python 2.5, bao gồm cElementTree phiên bản c (xml.etree.cElementTree), nhanh hơn 20 lần so với phiên bản Python thuần túy và rất dễ sử dụng.

lxml có một số ưu điểm về lưu lượng, nhưng chúng không đồng đều và bạn nên kiểm tra điểm chuẩn trước cho trường hợp sử dụng của mình.

Theo tôi hiểu, mã ElementTree có thể dễ dàng được chuyển sang lxml.


6

Nó phụ thuộc một chút vào mức độ phức tạp của tài liệu.

Tôi đã sử dụng minidom rất nhiều để viết XML, nhưng đó thường chỉ là đọc tài liệu, thực hiện một số biến đổi đơn giản và viết lại chúng. Điều đó hoạt động đủ tốt cho đến khi tôi cần khả năng sắp xếp các thuộc tính phần tử (để đáp ứng một ứng dụng cổ không phân tích cú pháp XML đúng cách). Tại thời điểm đó, tôi đã từ bỏ và tự viết XML.

Nếu bạn chỉ làm việc trên các tài liệu đơn giản, thì việc tự làm có thể nhanh chóng và đơn giản hơn so với việc học một khuôn khổ. Nếu bạn có thể hình dung được XML bằng tay, thì bạn cũng có thể viết mã nó bằng tay (chỉ cần nhớ thoát đúng các ký tự đặc biệt và sử dụng str.encode(codec, errors="xmlcharrefreplace")). Ngoài những snafus này, XML đủ thông thường để bạn không cần một thư viện đặc biệt để viết nó. Nếu tài liệu quá phức tạp để viết bằng tay, thì có lẽ bạn nên xem xét một trong các khuôn khổ đã được đề cập. Bạn không cần phải viết một trình viết XML tổng quát.


5

Bạn cũng có thể thử gỡ rối để phân tích cú pháp các tài liệu XML đơn giản.


4

Vì bạn đã đề cập rằng bạn sẽ xây dựng XML "khá đơn giản", mô-đun minidom (một phần của Thư viện chuẩn Python) có thể sẽ phù hợp với nhu cầu của bạn. Nếu bạn có bất kỳ kinh nghiệm nào với biểu diễn DOM của XML, bạn sẽ thấy API khá tốt.


4

Tôi viết một máy chủ SOAP nhận yêu cầu XML và tạo phản hồi XML. (Thật không may, nó không phải là dự án của tôi, vì vậy nó là nguồn đóng, nhưng đó là một vấn đề khác).

Đối với tôi, việc tạo tài liệu XML (SOAP) khá đơn giản nếu bạn có cấu trúc dữ liệu "phù hợp" với lược đồ.

Tôi giữ phong bì vì phong bì phản hồi (gần như) giống với phong bì yêu cầu. Sau đó, vì cấu trúc dữ liệu của tôi là một từ điển (có thể lồng nhau), tôi tạo một chuỗi biến từ điển này thành các mục <key> giá trị </key>.

Đây là một nhiệm vụ mà đệ quy làm cho đơn giản, và tôi kết thúc với cấu trúc đúng. Tất cả điều này được thực hiện bằng mã python và hiện đủ nhanh để sử dụng trong sản xuất.

Bạn cũng có thể (tương đối) dễ dàng xây dựng danh sách, mặc dù tùy thuộc vào khách hàng của bạn, bạn có thể gặp vấn đề trừ khi bạn đưa ra gợi ý về độ dài.

Đối với tôi, điều này đơn giản hơn nhiều, vì từ điển là một cách làm việc dễ dàng hơn nhiều so với một số lớp tùy chỉnh. Đối với sách, việc tạo XML dễ dàng hơn nhiều so với phân tích cú pháp!


3

Đối với công việc nghiêm túc với XML trong Python, hãy sử dụng lxml

Python đi kèm với thư viện tích hợp ElementTree, nhưng lxml mở rộng nó về tốc độ và chức năng (xác thực lược đồ, phân tích cú pháp sax, XPath, nhiều loại trình vòng lặp và nhiều tính năng khác).

Bạn phải cài đặt nó, nhưng ở nhiều nơi, nó đã được coi là một phần của thiết bị tiêu chuẩn (ví dụ: Google AppEngine không cho phép các gói Python dựa trên C, nhưng tạo một ngoại lệ cho lxml, pyyaml ​​và một số gói khác).

Xây dựng tài liệu XML với E-factory (từ lxml)

Câu hỏi của bạn là về việc xây dựng tài liệu XML.

Với lxml, có rất nhiều phương pháp và tôi đã mất một lúc để tìm ra một phương pháp, có vẻ dễ sử dụng và cũng dễ đọc.

Mã mẫu từ tài liệu lxml khi sử dụng E-factory (đơn giản hóa một chút):


E-factory cung cấp một cú pháp đơn giản và nhỏ gọn để tạo XML và HTML:

>>> from lxml.builder import E

>>> html = page = (
...   E.html(       # create an Element called "html"
...     E.head(
...       E.title("This is a sample document")
...     ),
...     E.body(
...       E.h1("Hello!"),
...       E.p("This is a paragraph with ", E.b("bold"), " text in it!"),
...       E.p("This is another paragraph, with a", "\n      ",
...         E.a("link", href="http://www.python.org"), "."),
...       E.p("Here are some reserved characters: <spam&egg>."),
...     )
...   )
... )

>>> print(etree.tostring(page, pretty_print=True))
<html>
  <head>
    <title>This is a sample document</title>
  </head>
  <body>
    <h1>Hello!</h1>
    <p>This is a paragraph with <b>bold</b> text in it!</p>
    <p>This is another paragraph, with a
      <a href="http://www.python.org">link</a>.</p>
    <p>Here are some reserved characters: &lt;spam&amp;egg&gt;.</p>
  </body>
</html>

Tôi đánh giá cao trên E-factory nó sau những điều

Mã đọc gần như tài liệu XML kết quả

Số lượng khả năng đọc.

Cho phép tạo bất kỳ nội dung XML nào

Hỗ trợ những thứ như:

  • sử dụng không gian tên
  • các nút văn bản bắt đầu và kết thúc trong một phần tử
  • chức năng định dạng nội dung thuộc tính (xem func CLASS trong mẫu lxml đầy đủ )

Cho phép các cấu trúc rất dễ đọc với danh sách

ví dụ:

from lxml import etree
from lxml.builder import E
lst = ["alfa", "beta", "gama"]
xml = E.root(*[E.record(itm) for itm in lst])
etree.tostring(xml, pretty_print=True)

dẫn đến:

<root>
  <record>alfa</record>
  <record>beta</record>
  <record>gama</record>
</root>

Kết luận

Tôi thực sự khuyên bạn nên đọc hướng dẫn lxml - nó được viết rất tốt và sẽ cho bạn nhiều lý do hơn để sử dụng thư viện mạnh mẽ này.

Nhược điểm duy nhất của lxml là nó phải được biên dịch. Xem câu trả lời SO để biết thêm mẹo về cách cài đặt lxml từ gói định dạng bánh xe trong vòng một phần của giây.


1

Nếu bạn định xây dựng thông báo SOAP, hãy xem soaplib . Nó sử dụng ElementTree dưới mui xe, nhưng nó cung cấp một giao diện sạch hơn nhiều để tuần tự hóa và giải mã thư.


1

Tôi thực sự khuyên bạn nên SAX - Simple API for XMLtriển khai trong các thư viện Python. Chúng khá dễ dàng để thiết lập và xử lý lớn XMLtheo hướng thậm chí API, như đã được thảo luận bởi các áp phích trước ở đây và có dung lượng bộ nhớ thấp không giống như các trình phân tích cú pháp DOMkiểu xác thực XML.


1

Tôi giả định rằng cách xử lý XML của .NET được xây dựng dựa trên một số phiên bản MSXML và trong trường hợp đó, tôi giả định rằng việc sử dụng minidom chẳng hạn sẽ khiến bạn cảm thấy như ở nhà. Tuy nhiên, nếu bạn đang xử lý đơn giản thì bất kỳ thư viện nào cũng có thể làm được.

Tôi cũng thích làm việc với ElementTree hơn khi xử lý XML bằng Python vì nó là một thư viện rất gọn gàng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.