Chuyển đổi XML thành đối tượng Python

Nếu bạn đã từng cố gắng phân tích cú pháp một tài liệu XML bằng Python trước đây, thì bạn sẽ biết nhiệm vụ đó khó đến mức nào. Một mặt, Zen of Python chỉ hứa hẹn một cách rõ ràng để đạt được mục tiêu của bạn. Đồng thời, thư viện chuẩn tuân theo phương châm bằng cách cho phép bạn chọn không chỉ một mà nhiều trình phân tích cú pháp XML. May mắn thay, cộng đồng Python đã giải quyết vấn đề dư thừa này bằng cách tạo ra nhiều thư viện phân tích cú pháp XML hơn nữa

Show

Đùa sang một bên, tất cả các trình phân tích cú pháp XML đều có vị trí của chúng trong một thế giới đầy những thách thức nhỏ hơn hoặc lớn hơn. Bạn nên làm quen với các công cụ có sẵn

Trong hướng dẫn này, bạn sẽ học cách

  • Chọn mô hình phân tích cú pháp XML phù hợp
  • Sử dụng các trình phân tích cú pháp XML trong thư viện chuẩn
  • Sử dụng các thư viện phân tích cú pháp XML chính
  • Phân tích tài liệu XML một cách khai báo bằng cách sử dụng liên kết dữ liệu
  • Sử dụng các trình phân tích cú pháp XML an toàn để loại bỏ các lỗ hổng bảo mật

Bạn có thể sử dụng hướng dẫn này như một lộ trình để hướng dẫn bạn vượt qua thế giới khó hiểu của các trình phân tích cú pháp XML trong Python. Cuối cùng, bạn sẽ có thể chọn đúng trình phân tích cú pháp XML cho một vấn đề nhất định. Để tận dụng tối đa hướng dẫn này, bạn nên làm quen với XML và các khối xây dựng của nó, cũng như cách làm việc với các tệp trong Python

Tiền thưởng miễn phí. 5 Suy nghĩ về Làm chủ Python, một khóa học miễn phí dành cho các nhà phát triển Python cho bạn thấy lộ trình và tư duy mà bạn sẽ cần để đưa các kỹ năng Python của mình lên một tầm cao mới

Chọn đúng mô hình phân tích cú pháp XML

Hóa ra là bạn có thể xử lý các tài liệu XML bằng một số chiến lược không phụ thuộc vào ngôn ngữ. Mỗi loại thể hiện sự đánh đổi bộ nhớ và tốc độ khác nhau, điều này có thể biện minh một phần cho nhiều loại trình phân tích cú pháp XML có sẵn trong Python. Trong phần sau, bạn sẽ tìm ra sự khác biệt và điểm mạnh của chúng

Loại bỏ các quảng cáo

Mô hình đối tượng tài liệu (DOM)

Trong lịch sử, mô hình đầu tiên và phổ biến nhất để phân tích cú pháp XML là DOM hoặc Mô hình đối tượng tài liệu, ban đầu được xác định bởi World Wide Web Consortium (W3C). Bạn có thể đã nghe nói về DOM vì trình duyệt web hiển thị giao diện DOM thông qua JavaScript để cho phép bạn thao tác mã HTML của trang web của mình. Cả XML và HTML đều thuộc cùng một họ ngôn ngữ đánh dấu, giúp cho việc phân tích cú pháp XML bằng DOM có thể thực hiện được

DOM được cho là mô hình đơn giản và linh hoạt nhất để sử dụng. Nó định nghĩa một số hoạt động tiêu chuẩn để duyệt qua và sửa đổi các phần tử tài liệu được sắp xếp theo thứ bậc của các đối tượng. Một biểu diễn trừu tượng của toàn bộ cây tài liệu được lưu trữ trong bộ nhớ, cho phép bạn truy cập ngẫu nhiên vào các thành phần riêng lẻ

Mặc dù cây DOM cho phép điều hướng nhanh và đa hướng, nhưng việc xây dựng biểu diễn trừu tượng của nó ngay từ đầu có thể tốn nhiều thời gian. Hơn nữa, toàn bộ XML được phân tích cú pháp cùng một lúc, do đó, nó phải có kích thước hợp lý để phù hợp với bộ nhớ khả dụng. Điều này làm cho DOM chỉ phù hợp với các tệp cấu hình lớn vừa phải thay vì cơ sở dữ liệu XML nhiều gigabyte

Sử dụng trình phân tích cú pháp DOM khi sự thuận tiện quan trọng hơn thời gian xử lý và khi bộ nhớ không phải là vấn đề. Một số trường hợp sử dụng điển hình là khi bạn cần phân tích cú pháp một tài liệu tương đối nhỏ hoặc khi bạn chỉ cần thực hiện phân tích cú pháp không thường xuyên

API đơn giản cho XML (SAX)

Để giải quyết những thiếu sót của DOM, cộng đồng Java đã đưa ra một thư viện thông qua nỗ lực hợp tác, thư viện này sau đó đã trở thành một mô hình thay thế để phân tích cú pháp XML bằng các ngôn ngữ khác. Không có đặc điểm kỹ thuật chính thức, chỉ có các cuộc thảo luận hữu cơ trên danh sách gửi thư. Kết quả cuối cùng là API phát trực tuyến dựa trên sự kiện hoạt động tuần tự trên các phần tử riêng lẻ thay vì toàn bộ cây

Các phần tử được xử lý từ trên xuống dưới theo cùng thứ tự chúng xuất hiện trong tài liệu. Trình phân tích cú pháp kích hoạt các cuộc gọi lại do người dùng xác định để xử lý các nút XML cụ thể khi nó tìm thấy chúng trong tài liệu. Cách tiếp cận này được gọi là phân tích cú pháp “đẩy” vì các phần tử được trình phân tích cú pháp đẩy đến các hàm của bạn

SAX cũng cho phép bạn loại bỏ các phần tử nếu bạn không quan tâm đến chúng. Điều này có nghĩa là nó có dung lượng bộ nhớ thấp hơn nhiều so với DOM và có thể xử lý các tệp lớn tùy ý, rất phù hợp cho xử lý một lần như lập chỉ mục, chuyển đổi sang các định dạng khác, v.v.

Tuy nhiên, việc tìm kiếm hoặc sửa đổi các nút cây ngẫu nhiên rất cồng kềnh vì nó thường yêu cầu nhiều lần chuyển tài liệu và theo dõi các nút đã truy cập. SAX cũng bất tiện khi xử lý các phần tử được lồng sâu. Cuối cùng, mô hình SAX chỉ cho phép phân tích cú pháp chỉ đọc

Nói tóm lại, SAX rẻ về không gian và thời gian nhưng khó sử dụng hơn DOM trong hầu hết các trường hợp. Nó hoạt động tốt để phân tích các tài liệu rất lớn hoặc phân tích dữ liệu XML đến trong thời gian thực

API truyền phát cho XML (StAX)

Mặc dù hơi ít phổ biến hơn trong Python, cách tiếp cận thứ ba này để phân tích cú pháp XML được xây dựng trên SAX. Nó mở rộng ý tưởng phát trực tuyến nhưng thay vào đó sử dụng mô hình phân tích cú pháp “kéo”, giúp bạn kiểm soát nhiều hơn. Bạn có thể nghĩ về StAX như một đối tượng con trỏ tiến lên thông qua một tài liệu XML, nơi các trình xử lý tùy chỉnh gọi trình phân tích cú pháp theo yêu cầu chứ không phải theo cách khác

Ghi chú. Có thể kết hợp nhiều hơn một mô hình phân tích cú pháp XML. Ví dụ: bạn có thể sử dụng SAX hoặc StAX để tìm nhanh một phần dữ liệu thú vị trong tài liệu và sau đó xây dựng biểu diễn DOM chỉ nhánh cụ thể đó trong bộ nhớ

Sử dụng StAX cho phép bạn kiểm soát nhiều hơn quá trình phân tích cú pháp và cho phép quản lý trạng thái thuận tiện hơn. Các sự kiện trong luồng chỉ được sử dụng khi được yêu cầu, cho phép đánh giá chậm. Ngoài ra, hiệu suất của nó phải ngang bằng với SAX, tùy thuộc vào việc triển khai trình phân tích cú pháp

Tìm hiểu về Trình phân tích cú pháp XML trong Thư viện chuẩn của Python

Trong phần này, bạn sẽ xem xét các trình phân tích cú pháp XML tích hợp sẵn của Python, chúng có sẵn cho bạn trong hầu hết mọi bản phân phối Python. Bạn sẽ so sánh các trình phân tích cú pháp đó với hình ảnh Đồ họa vectơ có thể mở rộng (SVG) mẫu, là định dạng dựa trên XML. Bằng cách xử lý cùng một tài liệu với các trình phân tích cú pháp khác nhau, bạn sẽ có thể chọn tài liệu phù hợp nhất với mình

Hình ảnh mẫu mà bạn sắp lưu vào tệp cục bộ để tham khảo, mô tả một khuôn mặt cười. Nó bao gồm nội dung XML sau

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
    <!ENTITY custom_entity "Hello">
]>
<svg xmlns="http://www.w3.org/2000/svg"
  xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
  viewBox="-105 -100 210 270" width="210" height="270">
  <inkscape:custom x="42" inkscape:z="555">Some value</inkscape:custom>
  <defs>
    <linearGradient id="skin" x1="0" x2="0" y1="0" y2="1">
      <stop offset="0%" stop-color="yellow" stop-opacity="1.0"/>
      <stop offset="75%" stop-color="gold" stop-opacity="1.0"/>
      <stop offset="100%" stop-color="orange" stop-opacity="1"/>
    </linearGradient>
  </defs>
  <g id="smiley" inkscape:groupmode="layer" inkscape:label="Smiley">
    <!-- Head -->
    <circle cx="0" cy="0" r="50"
      fill="url(#skin)" stroke="orange" stroke-width="2"/>
    <!-- Eyes -->
    <ellipse cx="-20" cy="-10" rx="6" ry="8" fill="black" stroke="none"/>
    <ellipse cx="20" cy="-10" rx="6" ry="8" fill="black" stroke="none"/>
    <!-- Mouth -->
    <path d="M-20 20 A25 25 0 0 0 20 20"
      fill="white" stroke="black" stroke-width="3"/>
  </g>
  <text x="-40" y="75">&custom_entity; &lt;svg&gt;!</text>
  <script>
    <![CDATA[
      console.log("CDATA disables XML parsing: <svg>")
      const smiley = document.getElementById("smiley")
      const eyes = document.querySelectorAll("ellipse")
      const setRadius = r => e => eyes.forEach(x => x.setAttribute("ry", r))
      smiley.addEventListener("mouseenter", setRadius(2))
      smiley.addEventListener("mouseleave", setRadius(8))
    ]]>
  </script>
</svg>

Nó bắt đầu bằng một khai báo XML, tiếp theo là Định nghĩa loại tài liệu (DTD) và phần tử gốc

>>> document.getElementsByTagNameNS(
..     "http://www.inkscape.org/namespaces/inkscape",
..     "custom"
.. )
...
[<DOM Element: inkscape:custom at 0x7f97e3f2a3a0>]

>>> document.getElementsByTagNameNS("*", "custom")
[<DOM Element: inkscape:custom at 0x7f97e3f2a3a0>]
9. DTD là tùy chọn, nhưng nó có thể giúp xác thực cấu trúc tài liệu của bạn nếu bạn quyết định sử dụng trình xác thực XML. Phần tử gốc chỉ định không gian tên mặc định
>>> element = document.getElementById("smiley")

>>> element.parentNode
<DOM Element: svg at 0x7fc78c62d790>

>>> element.firstChild
<DOM Text node "'\n    '">

>>> element.lastChild
<DOM Text node "'\n  '">

>>> element.nextSibling
<DOM Text node "'\n  '">

>>> element.previousSibling
<DOM Text node "'\n  '">
0 cũng như không gian tên có tiền tố
>>> element = document.getElementById("smiley")

>>> element.parentNode
<DOM Element: svg at 0x7fc78c62d790>

>>> element.firstChild
<DOM Text node "'\n    '">

>>> element.lastChild
<DOM Text node "'\n  '">

>>> element.nextSibling
<DOM Text node "'\n  '">

>>> element.previousSibling
<DOM Text node "'\n  '">
1 cho các phần tử và thuộc tính dành riêng cho trình soạn thảo. Tài liệu cũng chứa

  • các phần tử lồng nhau
  • Thuộc tính
  • Bình luận
  • Dữ liệu ký tự (______2_______2)
  • Các thực thể được xác định trước và tùy chỉnh

Hãy tiếp tục, lưu XML trong một tệp có tên là mặt cười. svg và mở nó bằng trình duyệt web hiện đại, trình duyệt này sẽ chạy đoạn mã JavaScript ở cuối

Chuyển đổi XML thành đối tượng Python

Mã thêm một thành phần tương tác vào hình ảnh. Khi bạn di chuột qua khuôn mặt cười, nó sẽ chớp mắt. Nếu bạn muốn chỉnh sửa mặt cười bằng giao diện người dùng đồ họa (GUI) thuận tiện, thì bạn có thể mở tệp bằng trình chỉnh sửa đồ họa vector như Adobe Illustrator hoặc Inkscape

Ghi chú. Không giống như JSON hay YAML, một số tính năng của XML có thể bị tin tặc khai thác. Các trình phân tích cú pháp XML tiêu chuẩn có sẵn trong gói

>>> element = document.getElementById("smiley")

>>> element.parentNode
<DOM Element: svg at 0x7fc78c62d790>

>>> element.firstChild
<DOM Text node "'\n    '">

>>> element.lastChild
<DOM Text node "'\n  '">

>>> element.nextSibling
<DOM Text node "'\n  '">

>>> element.previousSibling
<DOM Text node "'\n  '">
3 trong Python không an toàn và dễ bị tấn công. Để phân tích cú pháp các tài liệu XML một cách an toàn từ một nguồn không đáng tin cậy, hãy ưu tiên các giải pháp thay thế an toàn. Bạn có thể chuyển đến hướng dẫn này để biết thêm chi tiết

Điều đáng chú ý là thư viện chuẩn của Python định nghĩa các giao diện trừu tượng để phân tích cú pháp các tài liệu XML trong khi cho phép bạn cung cấp triển khai trình phân tích cú pháp cụ thể. Trong thực tế, bạn hiếm khi làm điều đó vì Python gói một liên kết cho thư viện Expat, đây là trình phân tích cú pháp XML nguồn mở được sử dụng rộng rãi được viết bằng C. Theo mặc định, tất cả các mô-đun Python sau trong thư viện tiêu chuẩn đều sử dụng Expat under the mui xe

Thật không may, mặc dù trình phân tích cú pháp người nước ngoài có thể cho bạn biết liệu tài liệu của bạn có được định dạng tốt hay không, nhưng nó không thể xác thực cấu trúc tài liệu của bạn dựa trên Định nghĩa lược đồ XML (XSD) hoặc Định nghĩa loại tài liệu (DTD). Để làm được điều đó, bạn sẽ phải sử dụng một trong các thư viện của bên thứ ba sẽ được thảo luận sau

Loại bỏ các quảng cáo

>>> element = document.getElementById("smiley") >>> element.parentNode <DOM Element: svg at 0x7fc78c62d790> >>> element.firstChild <DOM Text node "'\n '"> >>> element.lastChild <DOM Text node "'\n '"> >>> element.nextSibling <DOM Text node "'\n '"> >>> element.previousSibling <DOM Text node "'\n '"> 4. Triển khai DOM tối thiểu

Xét rằng việc phân tích cú pháp các tài liệu XML bằng DOM được cho là đơn giản nhất, bạn sẽ không ngạc nhiên khi tìm thấy một trình phân tích cú pháp DOM trong thư viện chuẩn của Python. Tuy nhiên, điều đáng ngạc nhiên là thực tế có hai trình phân tích cú pháp DOM

Gói

>>> element = document.getElementById("smiley")

>>> element.parentNode
<DOM Element: svg at 0x7fc78c62d790>

>>> element.firstChild
<DOM Text node "'\n    '">

>>> element.lastChild
<DOM Text node "'\n  '">

>>> element.nextSibling
<DOM Text node "'\n  '">

>>> element.previousSibling
<DOM Text node "'\n  '">
5 chứa hai mô-đun để hoạt động với DOM trong Python

  1. >>> element = document.getElementById("smiley")
    
    >>> element.parentNode
    <DOM Element: svg at 0x7fc78c62d790>
    
    >>> element.firstChild
    <DOM Text node "'\n    '">
    
    >>> element.lastChild
    <DOM Text node "'\n  '">
    
    >>> element.nextSibling
    <DOM Text node "'\n  '">
    
    >>> element.previousSibling
    <DOM Text node "'\n  '">
    
    4
  2. >>> element = document.getElementById("smiley")
    
    >>> element.parentNode
    <DOM Element: svg at 0x7fc78c62d790>
    
    >>> element.firstChild
    <DOM Text node "'\n    '">
    
    >>> element.lastChild
    <DOM Text node "'\n  '">
    
    >>> element.nextSibling
    <DOM Text node "'\n  '">
    
    >>> element.previousSibling
    <DOM Text node "'\n  '">
    
    7

Đầu tiên là triển khai rút gọn giao diện DOM tuân theo phiên bản tương đối cũ của đặc tả W3C. Nó cung cấp các đối tượng phổ biến được xác định bởi API DOM, chẳng hạn như

>>> element = document.getElementById("smiley")

>>> element.parentNode
<DOM Element: svg at 0x7fc78c62d790>

>>> element.firstChild
<DOM Text node "'\n    '">

>>> element.lastChild
<DOM Text node "'\n  '">

>>> element.nextSibling
<DOM Text node "'\n  '">

>>> element.previousSibling
<DOM Text node "'\n  '">
8,
>>> element = document.getElementById("smiley")

>>> element.parentNode
<DOM Element: svg at 0x7fc78c62d790>

>>> element.firstChild
<DOM Text node "'\n    '">

>>> element.lastChild
<DOM Text node "'\n  '">

>>> element.nextSibling
<DOM Text node "'\n  '">

>>> element.previousSibling
<DOM Text node "'\n  '">
9 và
>>> def remove_whitespace(node):
..     if node.nodeType == Node.TEXT_NODE:
..         if node.nodeValue.strip() == "":
..             node.nodeValue = ""
..     for child in node.childNodes:
..         remove_whitespace(child)
...
>>> document = parse("smiley.svg")
>>> set_id_attribute(document)
>>> remove_whitespace(document)
>>> document.normalize()
0. Mô-đun này ít tài liệu và có tính hữu dụng khá hạn chế, vì bạn sắp tìm hiểu

Mô-đun thứ hai có tên hơi gây hiểu lầm vì nó xác định trình phân tích cú pháp kéo luồng, có thể tùy chọn tạo biểu diễn DOM của nút hiện tại trong cây tài liệu. Bạn sẽ tìm thấy thêm thông tin về trình phân tích cú pháp

>>> def remove_whitespace(node):
..     if node.nodeType == Node.TEXT_NODE:
..         if node.nodeValue.strip() == "":
..             node.nodeValue = ""
..     for child in node.childNodes:
..         remove_whitespace(child)
...
>>> document = parse("smiley.svg")
>>> set_id_attribute(document)
>>> remove_whitespace(document)
>>> document.normalize()
1

Có hai chức năng trong

>>> def remove_whitespace(node):
..     if node.nodeType == Node.TEXT_NODE:
..         if node.nodeValue.strip() == "":
..             node.nodeValue = ""
..     for child in node.childNodes:
..         remove_whitespace(child)
...
>>> document = parse("smiley.svg")
>>> set_id_attribute(document)
>>> remove_whitespace(document)
>>> document.normalize()
2 cho phép bạn phân tích cú pháp dữ liệu XML từ nhiều nguồn dữ liệu khác nhau. Một cái chấp nhận tên tệp hoặc , trong khi một cái khác mong đợi một chuỗi Python

>>>

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)

Giúp nhúng một chuỗi ký tự nhiều dòng mà không cần sử dụng ký tự tiếp nối (

>>> def remove_whitespace(node):
..     if node.nodeType == Node.TEXT_NODE:
..         if node.nodeValue.strip() == "":
..             node.nodeValue = ""
..     for child in node.childNodes:
..         remove_whitespace(child)
...
>>> document = parse("smiley.svg")
>>> set_id_attribute(document)
>>> remove_whitespace(document)
>>> document.normalize()
3) ở cuối mỗi dòng. Trong mọi trường hợp, bạn sẽ kết thúc với một phiên bản
>>> element = document.getElementById("smiley")

>>> element.parentNode
<DOM Element: svg at 0x7fc78c62d790>

>>> element.firstChild
<DOM Text node "'\n    '">

>>> element.lastChild
<DOM Text node "'\n  '">

>>> element.nextSibling
<DOM Text node "'\n  '">

>>> element.previousSibling
<DOM Text node "'\n  '">
8, hiển thị giao diện DOM quen thuộc, cho phép bạn duyệt qua cây

Ngoài ra, bạn sẽ có thể truy cập khai báo XML, DTD và phần tử gốc

>>>

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>

Như bạn có thể thấy, mặc dù trình phân tích cú pháp XML mặc định trong Python không thể xác thực tài liệu, nhưng nó vẫn cho phép bạn kiểm tra

>>> def remove_whitespace(node):
..     if node.nodeType == Node.TEXT_NODE:
..         if node.nodeValue.strip() == "":
..             node.nodeValue = ""
..     for child in node.childNodes:
..         remove_whitespace(child)
...
>>> document = parse("smiley.svg")
>>> set_id_attribute(document)
>>> remove_whitespace(document)
>>> document.normalize()
5, DTD, nếu có. Lưu ý rằng khai báo XML và DTD là tùy chọn. Nếu khai báo XML hoặc một thuộc tính XML nhất định bị thiếu, thì các thuộc tính Python tương ứng sẽ là
>>> def remove_whitespace(node):
..     if node.nodeType == Node.TEXT_NODE:
..         if node.nodeValue.strip() == "":
..             node.nodeValue = ""
..     for child in node.childNodes:
..         remove_whitespace(child)
...
>>> document = parse("smiley.svg")
>>> set_id_attribute(document)
>>> remove_whitespace(document)
>>> document.normalize()
6

Để tìm phần tử theo ID, bạn phải sử dụng thể hiện

>>> element = document.getElementById("smiley")

>>> element.parentNode
<DOM Element: svg at 0x7fc78c62d790>

>>> element.firstChild
<DOM Text node "'\n    '">

>>> element.lastChild
<DOM Text node "'\n  '">

>>> element.nextSibling
<DOM Text node "'\n  '">

>>> element.previousSibling
<DOM Text node "'\n  '">
8 thay vì cha cụ thể
>>> element = document.getElementById("smiley")

>>> element.parentNode
<DOM Element: svg at 0x7fc78c62d790>

>>> element.firstChild
<DOM Text node "'\n    '">

>>> element.lastChild
<DOM Text node "'\n  '">

>>> element.nextSibling
<DOM Text node "'\n  '">

>>> element.previousSibling
<DOM Text node "'\n  '">
9. Hình ảnh SVG mẫu có hai nút có thuộc tính
>>> def remove_whitespace(node):
..     if node.nodeType == Node.TEXT_NODE:
..         if node.nodeValue.strip() == "":
..             node.nodeValue = ""
..     for child in node.childNodes:
..         remove_whitespace(child)
...
>>> document = parse("smiley.svg")
>>> set_id_attribute(document)
>>> remove_whitespace(document)
>>> document.normalize()
9, nhưng bạn không thể tìm thấy một trong hai nút đó

>>>

>>> document.getElementById("skin") is None
True
>>> document.getElementById("smiley") is None
True

Điều đó có thể gây ngạc nhiên cho những người chỉ làm việc với HTML và JavaScript nhưng chưa từng làm việc với XML trước đây. Trong khi HTML xác định ngữ nghĩa cho các phần tử và thuộc tính nhất định, chẳng hạn như

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
00 hoặc
>>> def remove_whitespace(node):
..     if node.nodeType == Node.TEXT_NODE:
..         if node.nodeValue.strip() == "":
..             node.nodeValue = ""
..     for child in node.childNodes:
..         remove_whitespace(child)
...
>>> document = parse("smiley.svg")
>>> set_id_attribute(document)
>>> remove_whitespace(document)
>>> document.normalize()
9, thì XML không gắn bất kỳ ý nghĩa nào vào các khối xây dựng của nó. Ví dụ, bạn cần đánh dấu một thuộc tính là ID một cách rõ ràng bằng cách sử dụng DTD hoặc bằng cách gọi ____
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
02 bằng Python

Definition StyleImplementationDTD

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
03Python
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
04

Tuy nhiên, sử dụng DTD là không đủ để khắc phục sự cố nếu tài liệu của bạn có không gian tên mặc định, đây là trường hợp của hình ảnh SVG mẫu. Để giải quyết vấn đề này, bạn có thể truy cập tất cả các phần tử theo cách đệ quy trong Python, kiểm tra xem chúng có thuộc tính

>>> def remove_whitespace(node):
..     if node.nodeType == Node.TEXT_NODE:
..         if node.nodeValue.strip() == "":
..             node.nodeValue = ""
..     for child in node.childNodes:
..         remove_whitespace(child)
...
>>> document = parse("smiley.svg")
>>> set_id_attribute(document)
>>> remove_whitespace(document)
>>> document.normalize()
9 hay không và chỉ ra đó là ID của chúng trong một lần

>>>

>>> from xml.dom.minidom import parse, Node

>>> def set_id_attribute(parent, attribute_name="id"):
..     if parent.nodeType == Node.ELEMENT_NODE:
..         if parent.hasAttribute(attribute_name):
..             parent.setIdAttribute(attribute_name)
..     for child in parent.childNodes:
..         set_id_attribute(child, attribute_name)
...
>>> document = parse("smiley.svg")
>>> set_id_attribute(document)

Hàm

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
06 tùy chỉnh của bạn lấy một phần tử cha và một tên tùy chọn cho thuộc tính nhận dạng, mặc định là
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
07. Khi bạn gọi hàm đó trên tài liệu SVG của mình, thì tất cả các phần tử con có thuộc tính
>>> def remove_whitespace(node):
..     if node.nodeType == Node.TEXT_NODE:
..         if node.nodeValue.strip() == "":
..             node.nodeValue = ""
..     for child in node.childNodes:
..         remove_whitespace(child)
...
>>> document = parse("smiley.svg")
>>> set_id_attribute(document)
>>> remove_whitespace(document)
>>> document.normalize()
9 sẽ có thể truy cập được thông qua API DOM

>>>

>>> document.getElementById("skin")
<DOM Element: linearGradient at 0x7f82247703a0>

>>> document.getElementById("smiley")
<DOM Element: g at 0x7f8224770940>

Bây giờ, bạn đang nhận được phần tử XML dự kiến ​​tương ứng với giá trị của thuộc tính

>>> def remove_whitespace(node):
..     if node.nodeType == Node.TEXT_NODE:
..         if node.nodeValue.strip() == "":
..             node.nodeValue = ""
..     for child in node.childNodes:
..         remove_whitespace(child)
...
>>> document = parse("smiley.svg")
>>> set_id_attribute(document)
>>> remove_whitespace(document)
>>> document.normalize()
9

Sử dụng ID cho phép tìm tối đa một phần tử duy nhất, nhưng bạn cũng có thể tìm tập hợp các phần tử tương tự theo tên thẻ của chúng. Không giống như phương pháp

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
10, bạn có thể gọi
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
11 trên tài liệu hoặc một phần tử gốc cụ thể để giảm phạm vi tìm kiếm

>>>

>>> document.getElementsByTagName("ellipse")
[
    <DOM Element: ellipse at 0x7fa2c944f430>,
    <DOM Element: ellipse at 0x7fa2c944f4c0>
]

>>> root = document.documentElement
>>> root.getElementsByTagName("ellipse")
[
    <DOM Element: ellipse at 0x7fa2c944f430>,
    <DOM Element: ellipse at 0x7fa2c944f4c0>
]

Lưu ý rằng

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
11 luôn trả về một danh sách các phần tử thay vì một phần tử đơn lẻ hoặc
>>> def remove_whitespace(node):
..     if node.nodeType == Node.TEXT_NODE:
..         if node.nodeValue.strip() == "":
..             node.nodeValue = ""
..     for child in node.childNodes:
..         remove_whitespace(child)
...
>>> document = parse("smiley.svg")
>>> set_id_attribute(document)
>>> remove_whitespace(document)
>>> document.normalize()
6. Quên nó khi bạn chuyển đổi giữa cả hai phương pháp là một nguồn lỗi phổ biến

Thật không may, các phần tử như

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
14 có tiền tố là mã định danh không gian tên sẽ không được đưa vào. Chúng phải được tìm kiếm bằng cách sử dụng
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
15, điều này mong đợi các đối số khác nhau

>>>

>>> document.getElementsByTagNameNS(
..     "http://www.inkscape.org/namespaces/inkscape",
..     "custom"
.. )
...
[<DOM Element: inkscape:custom at 0x7f97e3f2a3a0>]

>>> document.getElementsByTagNameNS("*", "custom")
[<DOM Element: inkscape:custom at 0x7f97e3f2a3a0>]

Đối số đầu tiên phải là không gian tên XML, thường có dạng tên miền, trong khi đối số thứ hai là tên thẻ. Lưu ý rằng tiền tố không gian tên không liên quan. Để tìm kiếm tất cả các không gian tên, bạn có thể cung cấp một ký tự đại diện (

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
16)

Ghi chú. Để tìm các không gian tên được khai báo trong tài liệu XML của bạn, bạn có thể kiểm tra các thuộc tính của phần tử gốc. Về lý thuyết, chúng có thể được khai báo trên bất kỳ phần tử nào, nhưng phần tử cấp cao nhất là nơi bạn thường tìm thấy chúng

Sau khi xác định được yếu tố mà bạn quan tâm, bạn có thể sử dụng yếu tố đó để đi bộ trên cây. Tuy nhiên, một điều khó hiểu khác với

>>> def remove_whitespace(node):
..     if node.nodeType == Node.TEXT_NODE:
..         if node.nodeValue.strip() == "":
..             node.nodeValue = ""
..     for child in node.childNodes:
..         remove_whitespace(child)
...
>>> document = parse("smiley.svg")
>>> set_id_attribute(document)
>>> remove_whitespace(document)
>>> document.normalize()
2 là cách nó xử lý các ký tự khoảng trắng giữa các phần tử

>>>

>>> element = document.getElementById("smiley")

>>> element.parentNode
<DOM Element: svg at 0x7fc78c62d790>

>>> element.firstChild
<DOM Text node "'\n    '">

>>> element.lastChild
<DOM Text node "'\n  '">

>>> element.nextSibling
<DOM Text node "'\n  '">

>>> element.previousSibling
<DOM Text node "'\n  '">

Các ký tự dòng mới và thụt đầu dòng được ghi lại dưới dạng các phần tử cây riêng biệt, đây là điều mà thông số kỹ thuật yêu cầu. Một số trình phân tích cú pháp cho phép bạn bỏ qua những điều này, nhưng không phải trình phân tích cú pháp Python. Tuy nhiên, những gì bạn có thể làm là thu gọn khoảng trắng trong các nút đó theo cách thủ công

>>>

>>> def remove_whitespace(node):
..     if node.nodeType == Node.TEXT_NODE:
..         if node.nodeValue.strip() == "":
..             node.nodeValue = ""
..     for child in node.childNodes:
..         remove_whitespace(child)
...
>>> document = parse("smiley.svg")
>>> set_id_attribute(document)
>>> remove_whitespace(document)
>>> document.normalize()

Lưu ý rằng bạn cũng phải kết hợp các nút văn bản liền kề với tài liệu. Nếu không, bạn có thể kết thúc với một loạt các phần tử XML dư thừa chỉ với khoảng trắng. Một lần nữa, đệ quy là cách duy nhất để truy cập các phần tử của cây vì bạn không thể lặp lại tài liệu và các phần tử của nó bằng một vòng lặp. Cuối cùng, điều này sẽ cung cấp cho bạn kết quả mong đợi

>>>

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
0

Các phần tử hiển thị một vài phương thức và thuộc tính hữu ích để cho phép bạn truy vấn chi tiết của chúng

>>>

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
1

Chẳng hạn, bạn có thể kiểm tra không gian tên, tên thẻ hoặc thuộc tính của phần tử. Nếu bạn yêu cầu một thuộc tính bị thiếu, thì bạn sẽ nhận được một chuỗi rỗng (

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
19)

Xử lý các thuộc tính không gian tên không khác nhiều. Bạn chỉ cần nhớ thêm tiền tố vào tên thuộc tính tương ứng hoặc cung cấp tên miền

>>>

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
2

Thật kỳ lạ, ký tự đại diện (

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
16) không hoạt động ở đây như đã làm với phương pháp
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
15 trước đây

Vì hướng dẫn này chỉ nói về phân tích cú pháp XML, nên bạn sẽ cần kiểm tra tài liệu

>>> def remove_whitespace(node):
..     if node.nodeType == Node.TEXT_NODE:
..         if node.nodeValue.strip() == "":
..             node.nodeValue = ""
..     for child in node.childNodes:
..         remove_whitespace(child)
...
>>> document = parse("smiley.svg")
>>> set_id_attribute(document)
>>> remove_whitespace(document)
>>> document.normalize()
2 để biết các phương pháp sửa đổi cây DOM. Họ chủ yếu tuân theo thông số kỹ thuật của W3C

Như bạn có thể thấy, mô-đun

>>> def remove_whitespace(node):
..     if node.nodeType == Node.TEXT_NODE:
..         if node.nodeValue.strip() == "":
..             node.nodeValue = ""
..     for child in node.childNodes:
..         remove_whitespace(child)
...
>>> document = parse("smiley.svg")
>>> set_id_attribute(document)
>>> remove_whitespace(document)
>>> document.normalize()
2 không quá tiện lợi. Ưu điểm chính của nó đến từ việc là một phần của thư viện chuẩn, có nghĩa là bạn không phải cài đặt bất kỳ phụ thuộc bên ngoài nào trong dự án của mình để làm việc với DOM

Loại bỏ các quảng cáo

>>> from xml.dom.minidom import parse, parseString >>> # Parse XML from a filename >>> document = parse("smiley.svg") >>> # Parse XML from a file object >>> with open("smiley.svg") as file: .. document = parse(file) ... >>> # Parse XML from a Python string >>> document = parseString("""\ .. <svg viewBox="-105 -100 210 270"> .. <!-- More content goes here.. --> .. </svg> .. """) 24. Giao diện SAX cho Python

Để bắt đầu làm việc với SAX trong Python, bạn có thể sử dụng các hàm thuận tiện

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
25 và
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
26 như trước, nhưng thay vào đó từ gói
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
24. Bạn cũng phải cung cấp thêm ít nhất một đối số bắt buộc, đó phải là một phiên bản trình xử lý nội dung. Theo tinh thần của Java, bạn cung cấp một lớp bằng cách phân lớp một lớp cơ sở cụ thể

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
3

Trình xử lý nội dung nhận một luồng sự kiện tương ứng với các phần tử trong tài liệu của bạn khi nó được phân tích cú pháp. Chạy mã này sẽ không làm được gì hữu ích vì lớp trình xử lý của bạn trống. Để làm cho nó hoạt động, bạn sẽ cần quá tải một hoặc nhiều từ lớp cha

Khởi động trình chỉnh sửa yêu thích của bạn, nhập mã sau đây và lưu nó vào một tệp có tên

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
28

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
4

Trình xử lý nội dung đã sửa đổi này in ra một số sự kiện trên đầu ra tiêu chuẩn. Trình phân tích cú pháp SAX sẽ gọi ba phương thức này cho bạn để phản hồi việc tìm thẻ bắt đầu, thẻ kết thúc và một số văn bản giữa chúng. Khi bạn mở một phiên tương tác của trình thông dịch Python, hãy nhập trình xử lý nội dung của bạn và chạy thử. Nó sẽ tạo ra đầu ra sau

>>>

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
5

Về cơ bản, đó là mẫu thiết kế của người quan sát, cho phép bạn dịch dần dần XML sang định dạng phân cấp khác. Giả sử bạn muốn chuyển đổi tệp SVG đó thành biểu diễn JSON được đơn giản hóa. Đầu tiên, bạn sẽ muốn lưu trữ đối tượng xử lý nội dung của mình trong một biến riêng biệt để trích xuất thông tin từ nó sau này

>>>

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
6

Vì trình phân tích cú pháp SAX phát ra các sự kiện mà không cung cấp bất kỳ ngữ cảnh nào về phần tử mà nó tìm thấy, nên bạn cần theo dõi vị trí của mình trong cây. Do đó, thật hợp lý khi đẩy và bật phần tử hiện tại lên một ngăn xếp mà bạn có thể mô phỏng thông qua danh sách Python thông thường. Bạn cũng có thể xác định thuộc tính trợ giúp

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
29 sẽ trả về phần tử cuối cùng được đặt trên đỉnh ngăn xếp

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
7

Khi trình phân tích cú pháp SAX tìm thấy một phần tử mới, bạn có thể nắm bắt ngay tên thẻ và các thuộc tính của nó trong khi tạo trình giữ chỗ cho các phần tử con và giá trị, cả hai đều là tùy chọn. Hiện tại, bạn có thể lưu trữ mọi phần tử dưới dạng đối tượng

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
30. Thay thế phương thức
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
31 hiện tại của bạn bằng một triển khai mới

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
8

Trình phân tích cú pháp SAX cung cấp cho bạn các thuộc tính dưới dạng thuộc tính mà bạn có thể chuyển đổi sang từ điển Python đơn giản bằng cách gọi hàm

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
32. Giá trị phần tử thường trải rộng trên nhiều phần mà bạn có thể nối bằng cách sử dụng toán tử cộng (
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
33) hoặc câu lệnh gán tăng thêm tương ứng

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
9

Tổng hợp văn bản theo cách như vậy sẽ đảm bảo rằng nội dung nhiều dòng kết thúc trong phần tử hiện tại. Ví dụ: thẻ

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
34 trong tệp SVG mẫu chứa sáu dòng mã JavaScript, kích hoạt các cuộc gọi riêng biệt tới cuộc gọi lại
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
35

Cuối cùng, khi trình phân tích cú pháp tình cờ gặp thẻ đóng, bạn có thể bật phần tử hiện tại khỏi ngăn xếp và nối nó vào phần tử con của cha mẹ nó. Nếu chỉ còn một phần tử, thì đó sẽ là thư mục gốc của tài liệu mà bạn nên giữ lại sau này. Ngoài ra, bạn có thể muốn xóa phần tử hiện tại bằng cách xóa các khóa có giá trị trống

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
0

Lưu ý rằng

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
36 là một hàm được định nghĩa bên ngoài thân lớp. Việc dọn dẹp phải được thực hiện sau cùng vì không có cách nào biết trước có thể có bao nhiêu đoạn văn bản cần nối. Bạn có thể mở rộng phần có thể thu gọn bên dưới để có mã xử lý nội dung hoàn chỉnh

Trình xử lý SAX dành cho Trình chuyển đổi SVG sang JSONHiển thị/Ẩn

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
1

Bây giờ, đã đến lúc thử nghiệm mọi thứ bằng cách phân tích cú pháp XML, trích xuất phần tử gốc từ trình xử lý nội dung của bạn và kết xuất nó thành một chuỗi JSON

>>>

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
2

Điều đáng chú ý là việc triển khai này không tăng bộ nhớ so với DOM vì nó xây dựng một biểu diễn trừu tượng của toàn bộ tài liệu giống như trước đây. Sự khác biệt là bạn đã tạo một biểu diễn từ điển tùy chỉnh thay vì cây DOM tiêu chuẩn. Tuy nhiên, bạn có thể tưởng tượng việc ghi trực tiếp vào một tệp hoặc cơ sở dữ liệu thay vì bộ nhớ trong khi nhận các sự kiện SAX. Điều đó sẽ nâng giới hạn bộ nhớ máy tính của bạn một cách hiệu quả

Nếu bạn muốn phân tích cú pháp các không gian tên XML, thì bạn sẽ cần tự tạo và định cấu hình trình phân tích cú pháp SAX bằng một chút mã soạn sẵn và cũng triển khai các lệnh gọi lại hơi khác

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
3

Các cuộc gọi lại này nhận các tham số bổ sung về không gian tên của phần tử. Để làm cho trình phân tích cú pháp SAX thực sự kích hoạt các cuộc gọi lại đó thay vì một số cuộc gọi lại trước đó, bạn phải bật hỗ trợ không gian tên XML một cách rõ ràng

>>>

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
4

Đặt tính năng này biến phần tử

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
37 thành một bộ bao gồm tên miền của không gian tên và tên thẻ

Gói

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
24 cung cấp giao diện trình phân tích cú pháp XML dựa trên sự kiện phù hợp được mô hình hóa sau API Java gốc. Nó có phần hạn chế so với DOM nhưng cũng đủ để triển khai trình phân tích cú pháp đẩy luồng XML cơ bản mà không cần dùng đến thư viện của bên thứ ba. Với suy nghĩ này, có sẵn một trình phân tích cú pháp kéo ít dài dòng hơn trong Python mà bạn sẽ khám phá tiếp theo

Loại bỏ các quảng cáo

>>> element = document.getElementById("smiley") >>> element.parentNode <DOM Element: svg at 0x7fc78c62d790> >>> element.firstChild <DOM Text node "'\n '"> >>> element.lastChild <DOM Text node "'\n '"> >>> element.nextSibling <DOM Text node "'\n '"> >>> element.previousSibling <DOM Text node "'\n '"> 7. Trình phân tích cú pháp kéo trực tuyến

Các trình phân tích cú pháp trong thư viện chuẩn của Python thường hoạt động cùng nhau. Ví dụ: mô-đun

>>> element = document.getElementById("smiley")

>>> element.parentNode
<DOM Element: svg at 0x7fc78c62d790>

>>> element.firstChild
<DOM Text node "'\n    '">

>>> element.lastChild
<DOM Text node "'\n  '">

>>> element.nextSibling
<DOM Text node "'\n  '">

>>> element.previousSibling
<DOM Text node "'\n  '">
7 kết thúc trình phân tích cú pháp từ
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
24 để tận dụng bộ đệm và đọc tài liệu theo từng đoạn. Đồng thời, nó sử dụng triển khai DOM mặc định từ
>>> element = document.getElementById("smiley")

>>> element.parentNode
<DOM Element: svg at 0x7fc78c62d790>

>>> element.firstChild
<DOM Text node "'\n    '">

>>> element.lastChild
<DOM Text node "'\n  '">

>>> element.nextSibling
<DOM Text node "'\n  '">

>>> element.previousSibling
<DOM Text node "'\n  '">
4 để biểu diễn các phần tử tài liệu. Tuy nhiên, những phần tử đó được xử lý lần lượt mà không có bất kỳ mối quan hệ nào cho đến khi bạn yêu cầu nó một cách rõ ràng

Ghi chú. Hỗ trợ không gian tên XML được bật theo mặc định trong

>>> element = document.getElementById("smiley")

>>> element.parentNode
<DOM Element: svg at 0x7fc78c62d790>

>>> element.firstChild
<DOM Text node "'\n    '">

>>> element.lastChild
<DOM Text node "'\n  '">

>>> element.nextSibling
<DOM Text node "'\n  '">

>>> element.previousSibling
<DOM Text node "'\n  '">
7

Mặc dù mô hình SAX tuân theo mẫu người quan sát, nhưng bạn có thể coi StAX là mẫu thiết kế trình lặp, cho phép bạn lặp qua một luồng sự kiện cố định. Một lần nữa, bạn có thể gọi các hàm quen thuộc

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
25 hoặc
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
26 được nhập từ mô-đun để phân tích cú pháp hình ảnh SVG

>>>

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
5

Chỉ mất vài dòng mã để phân tích tài liệu. Sự khác biệt nổi bật nhất giữa

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
24 và
>>> element = document.getElementById("smiley")

>>> element.parentNode
<DOM Element: svg at 0x7fc78c62d790>

>>> element.firstChild
<DOM Text node "'\n    '">

>>> element.lastChild
<DOM Text node "'\n  '">

>>> element.nextSibling
<DOM Text node "'\n  '">

>>> element.previousSibling
<DOM Text node "'\n  '">
7 là không có cuộc gọi lại vì bạn điều khiển toàn bộ quá trình. Bạn có nhiều tự do hơn trong việc cấu trúc mã của mình và bạn không cần sử dụng các lớp nếu không muốn

Lưu ý rằng các nút XML được lấy từ luồng có các loại được xác định trong

>>> element = document.getElementById("smiley")

>>> element.parentNode
<DOM Element: svg at 0x7fc78c62d790>

>>> element.firstChild
<DOM Text node "'\n    '">

>>> element.lastChild
<DOM Text node "'\n  '">

>>> element.nextSibling
<DOM Text node "'\n  '">

>>> element.previousSibling
<DOM Text node "'\n  '">
4. Nhưng nếu bạn kiểm tra cha mẹ, anh chị em và con cái của họ, thì bạn sẽ phát hiện ra họ không biết gì về nhau

>>>

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
6

Các thuộc tính liên quan trống. Dù sao, trình phân tích cú pháp kéo có thể trợ giúp theo cách tiếp cận kết hợp để tra cứu nhanh một số phần tử cha và xây dựng một cây DOM chỉ dành cho nhánh bắt nguồn từ nó

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
7

Bằng cách gọi

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
49 trên luồng sự kiện, về cơ bản, bạn di chuyển trình vòng lặp về phía trước và phân tích cú pháp các nút XML theo cách đệ quy cho đến khi tìm thấy thẻ đóng phù hợp của phần tử gốc. Nút kết quả sẽ có con với các thuộc tính được khởi tạo đúng cách. Hơn nữa, bạn sẽ có thể sử dụng các phương thức DOM trên chúng

Trình phân tích cú pháp kéo cung cấp một giải pháp thay thế thú vị cho DOM và SAX bằng cách kết hợp những điều tốt nhất của cả hai thế giới. Nó hiệu quả, linh hoạt và dễ sử dụng, dẫn đến mã nhỏ gọn hơn và dễ đọc hơn. Bạn cũng có thể sử dụng nó để xử lý nhiều tệp XML cùng lúc một cách dễ dàng hơn. Điều đó nói rằng, không có trình phân tích cú pháp XML nào được đề cập cho đến nay có thể phù hợp với sự sang trọng, đơn giản và đầy đủ của trình phân tích cú pháp cuối cùng xuất hiện trong thư viện chuẩn của Python

>>> from xml.dom.minidom import parse, parseString >>> # Parse XML from a filename >>> document = parse("smiley.svg") >>> # Parse XML from a file object >>> with open("smiley.svg") as file: .. document = parse(file) ... >>> # Parse XML from a Python string >>> document = parseString("""\ .. <svg viewBox="-105 -100 210 270"> .. <!-- More content goes here.. --> .. </svg> .. """) 50. Một sự thay thế nhẹ, Pythonic

Trình phân tích cú pháp XML mà bạn đã biết cho đến nay đã hoàn thành công việc. Tuy nhiên, chúng không phù hợp lắm với triết lý của Python, và đó không phải là ngẫu nhiên. Mặc dù DOM tuân theo đặc điểm kỹ thuật của W3C và SAX được mô hình hóa sau API Java, nhưng không cảm thấy đặc biệt Pythonic

Tệ hơn nữa, cả trình phân tích cú pháp DOM và SAX đều cảm thấy lỗi thời vì một số mã của chúng trong trình thông dịch CPython đã không thay đổi trong hơn hai thập kỷ. Tại thời điểm viết bài này, quá trình triển khai của chúng vẫn chưa hoàn thiện và thiếu các sơ khai đã nhập, điều này làm hỏng quá trình hoàn thành mã trong trình chỉnh sửa mã

Trong khi đó, Python 2. 5 đã mang đến một góc nhìn mới về phân tích cú pháp và viết các tài liệu XML—API ElementTree. Đó là một giao diện nhẹ, hiệu quả, trang nhã và giàu tính năng mà ngay cả một số thư viện của bên thứ ba cũng xây dựng trên đó. Để bắt đầu với nó, bạn phải nhập mô-đun

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
50, hơi khó hiểu. Do đó, theo thông lệ, việc xác định bí danh như thế này

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
8

Trong mã cũ hơn một chút, bạn có thể đã thấy mô-đun

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
52 được nhập thay thế. Đó là một triển khai nhanh hơn nhiều lần so với giao diện tương tự được viết bằng C. Ngày nay, mô-đun thông thường sử dụng triển khai nhanh bất cứ khi nào có thể, vì vậy bạn không cần phải bận tâm nữa

Bạn có thể sử dụng API ElementTree bằng cách sử dụng các chiến lược phân tích cú pháp khác nhau

Không tăng dầnTăng dần (Chặn)Tăng dần (Không chặn)

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
53✔️
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
54✔️
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
55✔️
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
56✔️

Chiến lược không gia tăng tải toàn bộ tài liệu vào bộ nhớ theo kiểu giống như DOM. Có hai hàm được đặt tên phù hợp trong mô-đun cho phép phân tích cú pháp tệp hoặc chuỗi Python có nội dung XML

>>>

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
9

Phân tích cú pháp một đối tượng tệp hoặc tên tệp bằng

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
25 trả về một thể hiện của lớp, đại diện cho toàn bộ hệ thống phân cấp phần tử. Mặt khác, phân tích một chuỗi bằng
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
59 sẽ trả về gốc cụ thể

Ngoài ra, bạn có thể đọc dần dần tài liệu XML bằng trình phân tích cú pháp kéo trực tuyến, tạo ra một chuỗi các sự kiện và phần tử

>>>

>>> document.getElementById("skin") is None
True
>>> document.getElementById("smiley") is None
True
0

Theo mặc định,

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
61 chỉ phát ra các sự kiện
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
62 được liên kết với thẻ XML đóng. Tuy nhiên, bạn cũng có thể đăng ký các sự kiện khác. Bạn có thể tìm thấy chúng với các hằng chuỗi chẳng hạn như
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
63

>>>

>>> document.getElementById("skin") is None
True
>>> document.getElementById("smiley") is None
True
1

Dưới đây là danh sách tất cả các loại sự kiện có sẵn

  • >>> from xml.dom.minidom import parse, parseString
    
    >>> # Parse XML from a filename
    >>> document = parse("smiley.svg")
    
    >>> # Parse XML from a file object
    >>> with open("smiley.svg") as file:
    ..     document = parse(file)
    ...
    
    >>> # Parse XML from a Python string
    >>> document = parseString("""\
    .. <svg viewBox="-105 -100 210 270">
    ..   <!-- More content goes here.. -->
    .. </svg>
    .. """)
    
    64. Bắt đầu một phần tử
  • >>> from xml.dom.minidom import parse, parseString
    
    >>> # Parse XML from a filename
    >>> document = parse("smiley.svg")
    
    >>> # Parse XML from a file object
    >>> with open("smiley.svg") as file:
    ..     document = parse(file)
    ...
    
    >>> # Parse XML from a Python string
    >>> document = parseString("""\
    .. <svg viewBox="-105 -100 210 270">
    ..   <!-- More content goes here.. -->
    .. </svg>
    .. """)
    
    62. Kết thúc một phần tử
  • >>> from xml.dom.minidom import parse, parseString
    
    >>> # Parse XML from a filename
    >>> document = parse("smiley.svg")
    
    >>> # Parse XML from a file object
    >>> with open("smiley.svg") as file:
    ..     document = parse(file)
    ...
    
    >>> # Parse XML from a Python string
    >>> document = parseString("""\
    .. <svg viewBox="-105 -100 210 270">
    ..   <!-- More content goes here.. -->
    .. </svg>
    .. """)
    
    66. yếu tố bình luận
  • >>> from xml.dom.minidom import parse, parseString
    
    >>> # Parse XML from a filename
    >>> document = parse("smiley.svg")
    
    >>> # Parse XML from a file object
    >>> with open("smiley.svg") as file:
    ..     document = parse(file)
    ...
    
    >>> # Parse XML from a Python string
    >>> document = parseString("""\
    .. <svg viewBox="-105 -100 210 270">
    ..   <!-- More content goes here.. -->
    .. </svg>
    .. """)
    
    67. Hướng dẫn xử lý, như trong XSL
  • >>> from xml.dom.minidom import parse, parseString
    
    >>> # Parse XML from a filename
    >>> document = parse("smiley.svg")
    
    >>> # Parse XML from a file object
    >>> with open("smiley.svg") as file:
    ..     document = parse(file)
    ...
    
    >>> # Parse XML from a Python string
    >>> document = parseString("""\
    .. <svg viewBox="-105 -100 210 270">
    ..   <!-- More content goes here.. -->
    .. </svg>
    .. """)
    
    68. Bắt đầu một không gian tên
  • >>> from xml.dom.minidom import parse, parseString
    
    >>> # Parse XML from a filename
    >>> document = parse("smiley.svg")
    
    >>> # Parse XML from a file object
    >>> with open("smiley.svg") as file:
    ..     document = parse(file)
    ...
    
    >>> # Parse XML from a Python string
    >>> document = parseString("""\
    .. <svg viewBox="-105 -100 210 270">
    ..   <!-- More content goes here.. -->
    .. </svg>
    .. """)
    
    69. Kết thúc một không gian tên

Nhược điểm của

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
61 là nó sử dụng các cuộc gọi chặn để đọc đoạn dữ liệu tiếp theo, điều này có thể không phù hợp với mã không đồng bộ chạy trên một luồng thực thi. Để giảm bớt điều đó, bạn có thể xem xét , dài dòng hơn một chút

>>> document.getElementById("skin") is None
True
>>> document.getElementById("smiley") is None
True
2

Ví dụ giả định này cung cấp cho trình phân tích cú pháp các đoạn XML có thể đến cách nhau vài giây. Sau khi có đủ nội dung, bạn có thể lặp lại một chuỗi các sự kiện và phần tử được trình phân tích cú pháp lưu vào bộ đệm. Chiến lược phân tích cú pháp gia tăng không chặn này cho phép phân tích cú pháp thực sự đồng thời nhiều tài liệu XML một cách nhanh chóng trong khi bạn tải chúng xuống

Các phần tử trong cây có thể thay đổi, có thể lặp lại và có thể lập chỉ mục. Chúng có chiều dài tương ứng với số con trực tiếp của chúng

>>>

>>> document.getElementById("skin") is None
True
>>> document.getElementById("smiley") is None
True
3

Tên thẻ có thể được bắt đầu bằng một không gian tên tùy chọn được đặt trong một cặp dấu ngoặc nhọn (

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
72). Không gian tên XML mặc định cũng xuất hiện ở đó khi được định nghĩa. Lưu ý cách gán hoán đổi trong dòng được đánh dấu đã làm cho phần tử
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
73 xuất hiện trước
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
74. Điều này cho thấy bản chất đột biến của trình tự

Dưới đây là một vài thuộc tính và phương thức phần tử đáng được đề cập

>>>

>>> document.getElementById("skin") is None
True
>>> document.getElementById("smiley") is None
True
4

Một trong những lợi ích của API này là cách nó sử dụng các kiểu dữ liệu gốc của Python. Ở trên, nó sử dụng từ điển Python cho các thuộc tính của phần tử. Trong các mô-đun trước, chúng được bọc trong các bộ điều hợp kém tiện lợi hơn. Không giống như DOM, API ElementTree không hiển thị các phương thức hoặc thuộc tính để đi qua cây theo bất kỳ hướng nào, nhưng có một số lựa chọn thay thế tốt hơn

Như bạn đã thấy trước đây, các thể hiện của lớp

>>> element = document.getElementById("smiley")

>>> element.parentNode
<DOM Element: svg at 0x7fc78c62d790>

>>> element.firstChild
<DOM Text node "'\n    '">

>>> element.lastChild
<DOM Text node "'\n  '">

>>> element.nextSibling
<DOM Text node "'\n  '">

>>> element.previousSibling
<DOM Text node "'\n  '">
9 triển khai giao thức trình tự, cho phép bạn lặp lại các phần tử con trực tiếp của chúng bằng một vòng lặp

>>>

>>> document.getElementById("skin") is None
True
>>> document.getElementById("smiley") is None
True
5

Bạn nhận được chuỗi con ngay lập tức của gốc. Tuy nhiên, để tìm hiểu sâu hơn về các hậu duệ lồng nhau, bạn sẽ phải gọi phương thức

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
76 trên phần tử tổ tiên

>>>

>>> document.getElementById("skin") is None
True
>>> document.getElementById("smiley") is None
True
6

Phần tử gốc chỉ có năm phần tử con nhưng có tổng cộng mười ba phần tử con. Cũng có thể thu hẹp các hậu duệ bằng cách chỉ lọc các tên thẻ cụ thể bằng cách sử dụng đối số

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
77 tùy chọn

>>>

>>> document.getElementById("skin") is None
True
>>> document.getElementById("smiley") is None
True
7

Lần này, bạn chỉ có hai phần tử

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
78. Hãy nhớ bao gồm không gian tên XML, chẳng hạn như
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
79, trong tên thẻ của bạn—miễn là nó được xác định. Mặt khác, nếu bạn chỉ cung cấp tên thẻ mà không có không gian tên phù hợp, thì bạn có thể có ít hoặc nhiều phần tử con hơn so với dự đoán ban đầu

Xử lý các không gian tên thuận tiện hơn khi sử dụng

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
80, chấp nhận ánh xạ tùy chọn tiền tố tới tên miền. Để chỉ ra không gian tên mặc định, bạn có thể để trống khóa hoặc gán tiền tố tùy ý, tiền tố này phải được sử dụng trong tên thẻ sau này

>>>

>>> document.getElementById("skin") is None
True
>>> document.getElementById("smiley") is None
True
8

Ánh xạ không gian tên cho phép bạn tham chiếu đến cùng một phần tử với các tiền tố khác nhau. Đáng ngạc nhiên, nếu bạn cố gắng tìm các phần tử

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
78 lồng nhau như trước đây, thì
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
80 sẽ không trả về bất kỳ thứ gì vì nó mong đợi một biểu thức XPath hơn là một tên thẻ đơn giản

>>>

>>> document.getElementById("skin") is None
True
>>> document.getElementById("smiley") is None
True
9

Tình cờ, chuỗi

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
83 lại là một đường dẫn hợp lệ so với phần tử
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
84 hiện tại, đó là lý do tại sao hàm trả về kết quả không trống trước đó. Tuy nhiên, để tìm các dấu chấm lửng được lồng sâu hơn một cấp trong cấu trúc phân cấp XML, bạn cần có biểu thức đường dẫn chi tiết hơn

ElementTree có ngôn ngữ nhỏ XPath, mà bạn có thể sử dụng để truy vấn các phần tử trong XML, tương tự như bộ chọn CSS trong HTML. Có những phương pháp khác chấp nhận một biểu thức như vậy

>>>

>>> from xml.dom.minidom import parse, Node

>>> def set_id_attribute(parent, attribute_name="id"):
..     if parent.nodeType == Node.ELEMENT_NODE:
..         if parent.hasAttribute(attribute_name):
..             parent.setIdAttribute(attribute_name)
..     for child in parent.childNodes:
..         set_id_attribute(child, attribute_name)
...
>>> document = parse("smiley.svg")
>>> set_id_attribute(document)
0

Trong khi

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
80 trả về các phần tử khớp một cách lười biếng, thì
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
86 trả về một danh sách và
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
87 chỉ trả về phần tử khớp đầu tiên. Tương tự, bạn có thể trích xuất văn bản nằm giữa thẻ mở và thẻ đóng của các phần tử bằng cách sử dụng
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
88 hoặc lấy văn bản bên trong của toàn bộ tài liệu bằng cách sử dụng
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
89

>>>

>>> from xml.dom.minidom import parse, Node

>>> def set_id_attribute(parent, attribute_name="id"):
..     if parent.nodeType == Node.ELEMENT_NODE:
..         if parent.hasAttribute(attribute_name):
..             parent.setIdAttribute(attribute_name)
..     for child in parent.childNodes:
..         set_id_attribute(child, attribute_name)
...
>>> document = parse("smiley.svg")
>>> set_id_attribute(document)
1

Trước tiên, bạn tìm kiếm văn bản được nhúng trong một thành phần XML cụ thể, sau đó tìm mọi nơi trong toàn bộ tài liệu. Tìm kiếm theo văn bản là một tính năng mạnh mẽ của API ElementTree. Có thể sao chép nó bằng cách sử dụng các trình phân tích cú pháp tích hợp khác, nhưng phải trả giá bằng độ phức tạp của mã tăng lên và ít tiện lợi hơn

API ElementTree có lẽ là một trong số chúng trực quan nhất. Đó là Pythonic, hiệu quả, mạnh mẽ và phổ quát. Trừ khi bạn có lý do cụ thể để sử dụng DOM hoặc SAX, đây sẽ là lựa chọn mặc định của bạn

Loại bỏ các quảng cáo

Khám phá các thư viện trình phân tích cú pháp XML của bên thứ ba

Đôi khi, việc tiếp cận các trình phân tích cú pháp XML trong thư viện tiêu chuẩn có thể khiến bạn cảm thấy giống như cầm búa tạ để đập một quả hạch. Vào những thời điểm khác, điều ngược lại và bạn mong muốn một trình phân tích cú pháp có thể làm được nhiều hơn thế. Ví dụ: bạn có thể muốn xác thực XML dựa trên một lược đồ hoặc sử dụng các biểu thức XPath nâng cao. Trong những tình huống đó, tốt nhất bạn nên kiểm tra các thư viện bên ngoài có sẵn trên PyPI

Dưới đây, bạn sẽ tìm thấy tuyển tập các thư viện bên ngoài với các mức độ phức tạp và phức tạp khác nhau

>>> from xml.dom.minidom import parse, parseString >>> # Parse XML from a filename >>> document = parse("smiley.svg") >>> # Parse XML from a file object >>> with open("smiley.svg") as file: .. document = parse(file) ... >>> # Parse XML from a Python string >>> document = parseString("""\ .. <svg viewBox="-105 -100 210 270"> .. <!-- More content goes here.. --> .. </svg> .. """) 90. Chuyển đổi XML thành đối tượng Python

Nếu bạn đang tìm kiếm một lớp lót có thể biến tài liệu XML của bạn thành một đối tượng Python, thì không cần tìm đâu xa. Mặc dù nó chưa được cập nhật trong một vài năm, nhưng thư viện

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
90 có thể sớm trở thành cách yêu thích của bạn để phân tích cú pháp XML bằng Python. Chỉ có một hàm cần nhớ và nó chấp nhận URL, tên tệp, đối tượng tệp hoặc chuỗi XML

>>>

>>> from xml.dom.minidom import parse, Node

>>> def set_id_attribute(parent, attribute_name="id"):
..     if parent.nodeType == Node.ELEMENT_NODE:
..         if parent.hasAttribute(attribute_name):
..             parent.setIdAttribute(attribute_name)
..     for child in parent.childNodes:
..         set_id_attribute(child, attribute_name)
...
>>> document = parse("smiley.svg")
>>> set_id_attribute(document)
2

Trong mỗi trường hợp, nó trả về một thể hiện của lớp

>>> element = document.getElementById("smiley")

>>> element.parentNode
<DOM Element: svg at 0x7fc78c62d790>

>>> element.firstChild
<DOM Text node "'\n    '">

>>> element.lastChild
<DOM Text node "'\n  '">

>>> element.nextSibling
<DOM Text node "'\n  '">

>>> element.previousSibling
<DOM Text node "'\n  '">
9. Bạn có thể sử dụng toán tử dấu chấm để truy cập các nút con của nó và cú pháp dấu ngoặc vuông để lấy các thuộc tính XML hoặc một trong các nút con theo chỉ mục. Ví dụ, để lấy phần tử gốc của tài liệu, bạn có thể truy cập nó như thể nó là thuộc tính của đối tượng. Để lấy một trong các thuộc tính XML của phần tử, bạn có thể chuyển tên của nó làm khóa từ điển

>>>

>>> from xml.dom.minidom import parse, Node

>>> def set_id_attribute(parent, attribute_name="id"):
..     if parent.nodeType == Node.ELEMENT_NODE:
..         if parent.hasAttribute(attribute_name):
..             parent.setIdAttribute(attribute_name)
..     for child in parent.childNodes:
..         set_id_attribute(child, attribute_name)
...
>>> document = parse("smiley.svg")
>>> set_id_attribute(document)
3

Không có tên chức năng hoặc phương pháp để nhớ. Thay vào đó, mỗi đối tượng được phân tích cú pháp là duy nhất, vì vậy bạn thực sự cần biết cấu trúc của tài liệu XML bên dưới để duyệt qua nó với ____15_______90

Để biết tên của phần tử gốc là gì, hãy gọi

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
94 trên tài liệu

>>>

>>> from xml.dom.minidom import parse, Node

>>> def set_id_attribute(parent, attribute_name="id"):
..     if parent.nodeType == Node.ELEMENT_NODE:
..         if parent.hasAttribute(attribute_name):
..             parent.setIdAttribute(attribute_name)
..     for child in parent.childNodes:
..         set_id_attribute(child, attribute_name)
...
>>> document = parse("smiley.svg")
>>> set_id_attribute(document)
4

Điều này tiết lộ tên của phần tử con ngay lập tức. Lưu ý rằng

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
90 xác định lại ý nghĩa của
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
94 cho các tài liệu được phân tích cú pháp của nó. Thông thường, bạn gọi hàm tích hợp này để kiểm tra một lớp hoặc mô-đun Python. Việc triển khai mặc định sẽ trả về một danh sách các tên thuộc tính thay vì các phần tử con của tài liệu XML

Nếu có nhiều hơn một phần tử con với tên thẻ đã cho, thì bạn có thể lặp lại chúng bằng một vòng lặp hoặc tham chiếu một phần tử theo chỉ mục

>>>

>>> from xml.dom.minidom import parse, Node

>>> def set_id_attribute(parent, attribute_name="id"):
..     if parent.nodeType == Node.ELEMENT_NODE:
..         if parent.hasAttribute(attribute_name):
..             parent.setIdAttribute(attribute_name)
..     for child in parent.childNodes:
..         set_id_attribute(child, attribute_name)
...
>>> document = parse("smiley.svg")
>>> set_id_attribute(document)
5

Bạn có thể nhận thấy rằng phần tử

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
14 đã được đổi tên thành
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
98. Thật không may, thư viện không thể xử lý tốt các không gian tên XML, vì vậy nếu đó là thứ bạn cần dựa vào, thì bạn phải tìm ở nơi khác

Do ký hiệu dấu chấm, tên thành phần trong tài liệu XML phải hợp lệ. Nếu không, thì

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
90 sẽ tự động viết lại tên của họ bằng cách thay thế các ký tự bị cấm bằng dấu gạch dưới

>>>

>>> from xml.dom.minidom import parse, Node

>>> def set_id_attribute(parent, attribute_name="id"):
..     if parent.nodeType == Node.ELEMENT_NODE:
..         if parent.hasAttribute(attribute_name):
..             parent.setIdAttribute(attribute_name)
..     for child in parent.childNodes:
..         set_id_attribute(child, attribute_name)
...
>>> document = parse("smiley.svg")
>>> set_id_attribute(document)
6

Tên thẻ của trẻ em không phải là thuộc tính đối tượng duy nhất bạn có thể truy cập. Các phần tử có một vài thuộc tính đối tượng được xác định trước có thể được hiển thị bằng cách gọi

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
00

>>>

>>> from xml.dom.minidom import parse, Node

>>> def set_id_attribute(parent, attribute_name="id"):
..     if parent.nodeType == Node.ELEMENT_NODE:
..         if parent.hasAttribute(attribute_name):
..             parent.setIdAttribute(attribute_name)
..     for child in parent.childNodes:
..         set_id_attribute(child, attribute_name)
...
>>> document = parse("smiley.svg")
>>> set_id_attribute(document)
7

Đằng sau hậu trường,

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
90 sử dụng trình phân tích cú pháp SAX tích hợp, nhưng vì thư viện được triển khai bằng Python thuần túy và tạo ra nhiều đối tượng hạng nặng, nên nó có hiệu suất kém đáng kể. Mặc dù nó được thiết kế để đọc các tài liệu nhỏ, nhưng bạn vẫn có thể kết hợp nó với một phương pháp khác để đọc các tệp XML nhiều gigabyte

Đây là cách. Nếu bạn truy cập kho lưu trữ Wikipedia, bạn có thể tải xuống một trong các tệp XML đã nén của họ. Cái ở trên cùng phải chứa ảnh chụp nhanh phần tóm tắt của bài báo

>>> from xml.dom.minidom import parse, Node

>>> def set_id_attribute(parent, attribute_name="id"):
..     if parent.nodeType == Node.ELEMENT_NODE:
..         if parent.hasAttribute(attribute_name):
..             parent.setIdAttribute(attribute_name)
..     for child in parent.childNodes:
..         set_id_attribute(child, attribute_name)
...
>>> document = parse("smiley.svg")
>>> set_id_attribute(document)
8

Nó có kích thước hơn 6 GB sau khi tải xuống, rất phù hợp cho bài tập này. Ý tưởng là quét tệp để tìm các thẻ

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
02 mở và đóng liên tiếp, sau đó phân tích cú pháp đoạn XML giữa chúng bằng cách sử dụng
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
90 để thuận tiện

Mô-đun

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
04 tích hợp cho phép bạn tạo chế độ xem ảo cho nội dung tệp, ngay cả khi nó không vừa với bộ nhớ khả dụng. Điều này mang lại ấn tượng khi làm việc với một chuỗi byte khổng lồ hỗ trợ tìm kiếm và cú pháp cắt thông thường. Nếu bạn quan tâm đến cách đóng gói logic này trong a và tận dụng trình tạo để đánh giá lười biếng, thì hãy mở rộng phần có thể thu gọn bên dưới

Phương pháp kết hợp để phân tích cú pháp XMLHiển thị/Ẩn

Đây là mã hoàn chỉnh của lớp

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
05

>>> from xml.dom.minidom import parse, Node

>>> def set_id_attribute(parent, attribute_name="id"):
..     if parent.nodeType == Node.ELEMENT_NODE:
..         if parent.hasAttribute(attribute_name):
..             parent.setIdAttribute(attribute_name)
..     for child in parent.childNodes:
..         set_id_attribute(child, attribute_name)
...
>>> document = parse("smiley.svg")
>>> set_id_attribute(document)
9

Đó là trình quản lý ngữ cảnh tùy chỉnh, sử dụng giao thức trình vòng lặp được định nghĩa là hàm tạo nội tuyến. Đối tượng trình tạo kết quả lặp qua tài liệu XML như thể đó là một dòng ký tự dài

Lưu ý rằng vòng lặp

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
06 tận dụng cú pháp khá mới của Python, toán tử hải mã (
>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
07), để đơn giản hóa mã. Bạn có thể sử dụng toán tử này trong các biểu thức gán, trong đó một biểu thức có thể được đánh giá và gán cho một biến

Không đi sâu vào các chi tiết thực chất, đây là cách bạn có thể sử dụng lớp tùy chỉnh này để duyệt nhanh một tệp XML lớn trong khi kiểm tra các phần tử cụ thể kỹ lưỡng hơn với

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
90

>>>

>>> document.getElementById("skin")
<DOM Element: linearGradient at 0x7f82247703a0>

>>> document.getElementById("smiley")
<DOM Element: g at 0x7f8224770940>
0

Đầu tiên, bạn mở một tệp để đọc và cho biết tên thẻ mà bạn muốn tìm. Sau đó, bạn lặp lại các phần tử đó và nhận được một đoạn được phân tích cú pháp của tài liệu XML. Nó gần giống như nhìn qua một cửa sổ nhỏ di chuyển trên một tờ giấy dài vô tận. Đó là một ví dụ tương đối ở cấp độ bề mặt, bỏ qua một vài chi tiết, nhưng nó sẽ cung cấp cho bạn ý tưởng chung về cách sử dụng chiến lược phân tích cú pháp kết hợp như vậy

Loại bỏ các quảng cáo

>>> document = parse("smiley.svg") >>> # XML Declaration >>> document.version, document.encoding, document.standalone ('1.0', 'UTF-8', False) >>> # Document Type Definition (DTD) >>> dtd = document.doctype >>> dtd.entities["custom_entity"].childNodes [<DOM Text node "'Hello'">] >>> # Document Root >>> document.documentElement <DOM Element: svg at 0x7fc78c62d790> 09. Chuyển đổi XML sang từ điển Python

Nếu bạn thích JSON nhưng bạn không phải là người hâm mộ XML, thì hãy xem

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
09, nó cố gắng thu hẹp khoảng cách giữa cả hai định dạng dữ liệu. Đúng như tên gọi, thư viện có thể phân tích cú pháp một tài liệu XML và biểu thị nó dưới dạng một từ điển Python, đây cũng là loại dữ liệu đích cho các tài liệu JSON trong Python. Điều này làm cho việc chuyển đổi giữa XML và JSON có thể thực hiện được

Ghi chú. Từ điển được tạo thành từ các cặp khóa-giá trị, trong khi các tài liệu XML vốn đã được phân cấp, điều này có thể dẫn đến mất một số thông tin trong quá trình chuyển đổi. Trên hết, XML có các thuộc tính, nhận xét, hướng dẫn xử lý và các cách khác để xác định siêu dữ liệu không có sẵn trong từ điển

Không giống như phần còn lại của các trình phân tích cú pháp XML cho đến nay, trình phân tích cú pháp này mong đợi một chuỗi Python hoặc một đối tượng giống như tệp mở để đọc ở chế độ nhị phân

>>>

>>> document.getElementById("skin")
<DOM Element: linearGradient at 0x7f82247703a0>

>>> document.getElementById("smiley")
<DOM Element: g at 0x7f8224770940>
1

Theo mặc định, thư viện trả về một thể hiện của bộ sưu tập

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
11 để giữ nguyên thứ tự phần tử. Tuy nhiên, bắt đầu từ Python 3. 6, từ điển đơn giản cũng giữ thứ tự chèn. Thay vào đó, nếu bạn muốn làm việc với các từ điển thông thường, thì hãy chuyển
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
30 làm đối số
>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
13 cho hàm
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
25

>>>

>>> document.getElementById("skin")
<DOM Element: linearGradient at 0x7f82247703a0>

>>> document.getElementById("smiley")
<DOM Element: g at 0x7f8224770940>
2

Bây giờ,

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
25 trả về một từ điển cũ đơn giản với cách trình bày văn bản quen thuộc

Để tránh xung đột tên giữa các phần tử XML và các thuộc tính của chúng, thư viện sẽ tự động đặt tiền tố cho phần tử sau bằng ký tự

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
16. Bạn cũng có thể bỏ qua hoàn toàn các thuộc tính bằng cách đặt cờ
>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
17 một cách thích hợp

>>>

>>> document.getElementById("skin")
<DOM Element: linearGradient at 0x7f82247703a0>

>>> document.getElementById("smiley")
<DOM Element: g at 0x7f8224770940>
3

Tuy nhiên, một phần thông tin khác bị bỏ qua theo mặc định là khai báo không gian tên XML. Chúng được coi như các thuộc tính thông thường, trong khi các tiền tố tương ứng trở thành một phần của tên thẻ. Tuy nhiên, bạn có thể mở rộng, đổi tên hoặc bỏ qua một số không gian tên nếu muốn

>>>

>>> document.getElementById("skin")
<DOM Element: linearGradient at 0x7f82247703a0>

>>> document.getElementById("smiley")
<DOM Element: g at 0x7f8224770940>
4

Trong ví dụ đầu tiên ở trên, tên thẻ không bao gồm tiền tố không gian tên XML. Trong ví dụ thứ hai, chúng làm như vậy vì bạn đã yêu cầu xử lý chúng. Cuối cùng, trong ví dụ thứ ba, bạn đã thu gọn không gian tên mặc định thành

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
18 trong khi loại bỏ không gian tên của Inkscape bằng
>>> def remove_whitespace(node):
..     if node.nodeType == Node.TEXT_NODE:
..         if node.nodeValue.strip() == "":
..             node.nodeValue = ""
..     for child in node.childNodes:
..         remove_whitespace(child)
...
>>> document = parse("smiley.svg")
>>> set_id_attribute(document)
>>> remove_whitespace(document)
>>> document.normalize()
6

Biểu diễn chuỗi mặc định của từ điển Python có thể không đủ rõ ràng. Để cải thiện bản trình bày của nó, bạn có thể chuyển đổi nó sang định dạng khác như JSON hoặc YAML

>>>

>>> document.getElementById("skin")
<DOM Element: linearGradient at 0x7f82247703a0>

>>> document.getElementById("smiley")
<DOM Element: g at 0x7f8224770940>
5

Thư viện

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
09 cho phép chuyển đổi tài liệu theo cách khác—nghĩa là, từ một từ điển Python trở lại một chuỗi XML

>>>

>>> document.getElementById("skin")
<DOM Element: linearGradient at 0x7f82247703a0>

>>> document.getElementById("smiley")
<DOM Element: g at 0x7f8224770940>
6

Từ điển có thể hữu ích dưới dạng định dạng trung gian khi chuyển đổi dữ liệu từ JSON hoặc YAML sang XML, nếu có nhu cầu như vậy

Có rất nhiều tính năng khác trong thư viện

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
09, chẳng hạn như phát trực tuyến, vì vậy hãy tự mình khám phá chúng. Tuy nhiên, thư viện này cũng hơi cũ. Bên cạnh đó, đây là thư viện tiếp theo nên có trên radar của bạn nếu bạn thực sự đang tìm kiếm các tính năng phân tích cú pháp XML nâng cao

>>> document = parse("smiley.svg") >>> # XML Declaration >>> document.version, document.encoding, document.standalone ('1.0', 'UTF-8', False) >>> # Document Type Definition (DTD) >>> dtd = document.doctype >>> dtd.entities["custom_entity"].childNodes [<DOM Text node "'Hello'">] >>> # Document Root >>> document.documentElement <DOM Element: svg at 0x7fc78c62d790> 22. Sử dụng ElementTree trên Steroid

Nếu bạn muốn có hiệu suất tốt nhất, phạm vi chức năng rộng nhất và giao diện quen thuộc nhất, tất cả được gói gọn trong một gói, thì hãy cài đặt

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
22 và quên các thư viện còn lại đi. Đó là một liên kết Python cho các thư viện C libxml2 và libxslt, hỗ trợ một số tiêu chuẩn, bao gồm XPath, Lược đồ XML và XSLT

Thư viện tương thích với API ElementTree của Python mà bạn đã tìm hiểu trước đó trong hướng dẫn này. Điều đó có nghĩa là bạn có thể sử dụng lại mã hiện tại của mình bằng cách chỉ thay thế một câu lệnh nhập duy nhất

>>> document.getElementById("skin")
<DOM Element: linearGradient at 0x7f82247703a0>

>>> document.getElementById("smiley")
<DOM Element: g at 0x7f8224770940>
7

Điều này sẽ giúp bạn tăng hiệu suất tuyệt vời. Trên hết, thư viện

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
22 đi kèm với một bộ tính năng phong phú và cung cấp các cách sử dụng chúng khác nhau. Ví dụ: nó cho phép bạn xác thực các tài liệu XML của mình dựa trên một số ngôn ngữ lược đồ, một trong số đó là Định nghĩa lược đồ XML

>>>

>>> document.getElementById("skin")
<DOM Element: linearGradient at 0x7f82247703a0>

>>> document.getElementById("smiley")
<DOM Element: g at 0x7f8224770940>
8

Không có trình phân tích cú pháp XML nào trong thư viện chuẩn của Python có khả năng xác thực tài liệu. Trong khi đó,

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
22 cho phép bạn xác định một đối tượng
>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
26 và chạy các tài liệu thông qua nó trong khi phần lớn vẫn tương thích với API ElementTree

Bên cạnh API ElementTree,

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
22 hỗ trợ một lxml thay thế. đối tượng hóa giao diện mà bạn sẽ đề cập sau trong phần này

Loại bỏ các quảng cáo

>>> document = parse("smiley.svg") >>> # XML Declaration >>> document.version, document.encoding, document.standalone ('1.0', 'UTF-8', False) >>> # Document Type Definition (DTD) >>> dtd = document.doctype >>> dtd.entities["custom_entity"].childNodes [<DOM Text node "'Hello'">] >>> # Document Root >>> document.documentElement <DOM Element: svg at 0x7fc78c62d790> 28. Đối phó với XML không đúng định dạng

Thông thường, bạn sẽ không sử dụng thư viện cuối cùng trong phần so sánh này để phân tích cú pháp XML vì bạn hầu như gặp phải nó khi tìm kiếm các tài liệu HTML trên web. Điều đó nói rằng, nó cũng có khả năng phân tích cú pháp XML. BeautifulSoup đi kèm với kiến ​​trúc có thể cắm được cho phép bạn chọn trình phân tích cú pháp cơ bản.

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
22 được mô tả trước đó thực sự được đề xuất bởi tài liệu chính thức và hiện là trình phân tích cú pháp XML duy nhất được thư viện hỗ trợ

Tùy thuộc vào loại tài liệu bạn muốn phân tích cú pháp, hiệu quả mong muốn và tính khả dụng của tính năng, bạn có thể chọn một trong các trình phân tích cú pháp này

Document TypeParser NamePython LibrarySpeedHTML

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
30-ModerateHTML
>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
31
>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
32SlowHTML
>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
33
>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
22FastXML
>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
35 or
>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
36
>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
22Fast

Ngoài tốc độ, có sự khác biệt đáng chú ý giữa các trình phân tích cú pháp riêng lẻ. Ví dụ: một số trong số chúng dễ tha thứ hơn những cái khác khi nói đến các phần tử không đúng định dạng, trong khi những cái khác mô phỏng trình duyệt web tốt hơn

Sự thật thú vị. Tên của thư viện đề cập đến súp thẻ, mô tả mã HTML không chính xác về mặt cú pháp hoặc cấu trúc

Giả sử bạn đã cài đặt các thư viện

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
22 và
>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
39 vào môi trường ảo đang hoạt động của mình, bạn có thể bắt đầu phân tích cú pháp các tài liệu XML ngay lập tức. Bạn chỉ cần nhập
>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
28

>>> document.getElementById("skin")
<DOM Element: linearGradient at 0x7f82247703a0>

>>> document.getElementById("smiley")
<DOM Element: g at 0x7f8224770940>
9

Nếu bạn vô tình chỉ định một trình phân tích cú pháp khác, chẳng hạn như

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
22, thì thư viện sẽ thêm các thẻ HTML bị thiếu chẳng hạn như
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
00 vào tài liệu được phân tích cú pháp cho bạn. Đó có thể không phải là ý định của bạn trong trường hợp này, vì vậy hãy cẩn thận khi chỉ định tên trình phân tích cú pháp

BeautifulSoup là một công cụ mạnh mẽ để phân tích tài liệu XML vì nó có thể xử lý nội dung không hợp lệ và nó có API phong phú để trích xuất thông tin. Hãy xem cách nó đối phó với các thẻ được lồng không chính xác, các ký tự bị cấm và văn bản được đặt ở vị trí không phù hợp

>>> ______39_______0

Một trình phân tích cú pháp khác sẽ đưa ra một ngoại lệ và đầu hàng ngay khi phát hiện ra điều gì đó không ổn với tài liệu. Ở đây, nó không chỉ bỏ qua các vấn đề mà còn tìm ra những cách hợp lý để khắc phục một số vấn đề đó. Các phần tử hiện được lồng đúng cách và không có nội dung không hợp lệ

Có quá nhiều phương pháp định vị các phần tử với BeautifulSoup để trình bày tất cả ở đây. Thông thường, bạn sẽ gọi một biến thể của

>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
87 hoặc
>>> from xml.dom.minidom import parse, parseString

>>> # Parse XML from a filename
>>> document = parse("smiley.svg")

>>> # Parse XML from a file object
>>> with open("smiley.svg") as file:
..     document = parse(file)
...

>>> # Parse XML from a Python string
>>> document = parseString("""\
.. <svg viewBox="-105 -100 210 270">
..   <!-- More content goes here.. -->
.. </svg>
.. """)
86 trên phần tử súp

>>>

>>> document.getElementsByTagName("ellipse")
[
    <DOM Element: ellipse at 0x7fa2c944f430>,
    <DOM Element: ellipse at 0x7fa2c944f4c0>
]

>>> root = document.documentElement
>>> root.getElementsByTagName("ellipse")
[
    <DOM Element: ellipse at 0x7fa2c944f430>,
    <DOM Element: ellipse at 0x7fa2c944f4c0>
]
1

Tham số

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
45 tương tự như mệnh đề
>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
46 trong MySQL, cho phép bạn quyết định số lượng kết quả bạn muốn nhận nhiều nhất. Nó sẽ trả về số lượng kết quả được chỉ định hoặc ít hơn. Đó không phải là ngẫu nhiên. Bạn có thể coi các phương thức tìm kiếm này là một ngôn ngữ truy vấn đơn giản với các bộ lọc mạnh mẽ

Giao diện tìm kiếm rất linh hoạt nhưng nằm ngoài phạm vi của hướng dẫn này. Bạn có thể kiểm tra tài liệu của thư viện để biết thêm chi tiết hoặc đọc một hướng dẫn khác về quét web bằng Python liên quan đến BeautifulSoup

Liên kết dữ liệu XML với các đối tượng Python

Giả sử bạn muốn sử dụng nguồn cấp dữ liệu thời gian thực qua kết nối WebSocket có độ trễ thấp với các thông báo được trao đổi ở định dạng XML. Với mục đích của bài thuyết trình này, bạn sẽ sử dụng trình duyệt web để phát các sự kiện chuột và bàn phím của mình tới máy chủ Python. Bạn sẽ xây dựng một giao thức tùy chỉnh và sử dụng liên kết dữ liệu để dịch XML thành các đối tượng Python gốc

Ý tưởng đằng sau liên kết dữ liệu là xác định mô hình dữ liệu một cách khai báo trong khi để chương trình tìm ra cách trích xuất một phần thông tin có giá trị từ XML trong thời gian chạy. Nếu bạn đã từng làm việc với các mô hình Django, thì khái niệm này nghe có vẻ quen thuộc

Trước tiên, hãy bắt đầu bằng cách thiết kế mô hình dữ liệu của bạn. Nó sẽ bao gồm hai loại sự kiện

  1. >>> document = parse("smiley.svg")
    
    >>> # XML Declaration
    >>> document.version, document.encoding, document.standalone
    ('1.0', 'UTF-8', False)
    
    >>> # Document Type Definition (DTD)
    >>> dtd = document.doctype
    >>> dtd.entities["custom_entity"].childNodes
    [<DOM Text node "'Hello'">]
    
    >>> # Document Root
    >>> document.documentElement
    <DOM Element: svg at 0x7fc78c62d790>
    
    47
  2. >>> document = parse("smiley.svg")
    
    >>> # XML Declaration
    >>> document.version, document.encoding, document.standalone
    ('1.0', 'UTF-8', False)
    
    >>> # Document Type Definition (DTD)
    >>> dtd = document.doctype
    >>> dtd.entities["custom_entity"].childNodes
    [<DOM Text node "'Hello'">]
    
    >>> # Document Root
    >>> document.documentElement
    <DOM Element: svg at 0x7fc78c62d790>
    
    48

Mỗi cái có thể đại diện cho một vài loại phụ chuyên biệt, như nhấn phím hoặc nhả phím đối với bàn phím và nhấp hoặc nhấp chuột phải đối với chuột. Đây là một thông báo XML mẫu được tạo để phản hồi lại việc nhấn giữ Shift + 2 key combination:

>>> document.getElementsByTagName("ellipse")
[
    <DOM Element: ellipse at 0x7fa2c944f430>,
    <DOM Element: ellipse at 0x7fa2c944f4c0>
]

>>> root = document.documentElement
>>> root.getElementsByTagName("ellipse")
[
    <DOM Element: ellipse at 0x7fa2c944f430>,
    <DOM Element: ellipse at 0x7fa2c944f4c0>
]
2

Thông báo này chứa một loại sự kiện bàn phím cụ thể, dấu thời gian, mã khóa và Unicode của nó, cũng như các phím bổ trợ như Alt, Ctrl, or Shift. The meta key is usually the Win hoặc Cmd , tùy thuộc vào khóa của bạn. .

Tương tự, một sự kiện chuột có thể trông như thế này

>>> document.getElementsByTagName("ellipse")
[
    <DOM Element: ellipse at 0x7fa2c944f430>,
    <DOM Element: ellipse at 0x7fa2c944f4c0>
]

>>> root = document.documentElement
>>> root.getElementsByTagName("ellipse")
[
    <DOM Element: ellipse at 0x7fa2c944f430>,
    <DOM Element: ellipse at 0x7fa2c944f4c0>
]
3

Tuy nhiên, thay vì phím, có vị trí con trỏ chuột và trường bit mã hóa được nhấn trong sự kiện. Trường bit bằng 0 cho biết không có nút nào được nhấn

Ngay khi máy khách tạo kết nối, nó sẽ bắt đầu tràn ngập máy chủ với các thông báo. Giao thức sẽ không bao gồm bất kỳ cái bắt tay, nhịp tim, tắt máy duyên dáng, đăng ký chủ đề hoặc tin nhắn kiểm soát nào. Bạn có thể viết mã này bằng JavaScript bằng cách đăng ký trình xử lý sự kiện và tạo đối tượng

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
49 trong chưa đầy năm mươi dòng mã

Tuy nhiên, triển khai ứng dụng khách không phải là mục đích của bài tập này. Vì bạn không cần phải hiểu nó, chỉ cần mở rộng phần có thể thu gọn bên dưới để hiển thị mã HTML có nhúng JavaScript và lưu nó vào một tệp có tên tùy thích

Ứng dụng khách WebSocket bằng JavaScript và HTMLHiển thị/Ẩn

>>> document.getElementsByTagName("ellipse")
[
    <DOM Element: ellipse at 0x7fa2c944f430>,
    <DOM Element: ellipse at 0x7fa2c944f4c0>
]

>>> root = document.documentElement
>>> root.getElementsByTagName("ellipse")
[
    <DOM Element: ellipse at 0x7fa2c944f430>,
    <DOM Element: ellipse at 0x7fa2c944f4c0>
]
4

Máy khách kết nối với máy chủ cục bộ đang nghe trên cổng 8000. Khi bạn lưu mã HTML vào một tệp, bạn sẽ có thể mở nó bằng trình duyệt web yêu thích của mình. Nhưng trước đó, bạn sẽ cần triển khai máy chủ

Python không hỗ trợ WebSocket nhưng bạn có thể cài đặt thư viện

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
50 vào môi trường ảo đang hoạt động của mình. Bạn cũng sẽ cần
>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
22 sau này, vì vậy đây là thời điểm tốt để cài đặt cả hai phần phụ thuộc cùng một lúc

>>> document.getElementsByTagName("ellipse")
[
    <DOM Element: ellipse at 0x7fa2c944f430>,
    <DOM Element: ellipse at 0x7fa2c944f4c0>
]

>>> root = document.documentElement
>>> root.getElementsByTagName("ellipse")
[
    <DOM Element: ellipse at 0x7fa2c944f430>,
    <DOM Element: ellipse at 0x7fa2c944f4c0>
]
5

Cuối cùng, bạn có thể dàn dựng một máy chủ web không đồng bộ tối thiểu

>>> document.getElementsByTagName("ellipse")
[
    <DOM Element: ellipse at 0x7fa2c944f430>,
    <DOM Element: ellipse at 0x7fa2c944f4c0>
]

>>> root = document.documentElement
>>> root.getElementsByTagName("ellipse")
[
    <DOM Element: ellipse at 0x7fa2c944f430>,
    <DOM Element: ellipse at 0x7fa2c944f4c0>
]
6

Khi bạn khởi động máy chủ và mở tệp HTML đã lưu trong trình duyệt web, bạn sẽ thấy các thông báo XML xuất hiện trong đầu ra tiêu chuẩn để đáp ứng với các lần di chuyển chuột và nhấn phím của bạn. Bạn có thể mở ứng dụng khách trong nhiều tab hoặc thậm chí nhiều trình duyệt cùng một lúc

Loại bỏ các quảng cáo

Xác định mô hình với biểu thức XPath

Ngay bây giờ, tin nhắn của bạn đến ở định dạng chuỗi đơn giản. Nó không thuận tiện lắm khi làm việc với các tin nhắn ở định dạng này. May mắn thay, bạn có thể biến chúng thành các đối tượng Python phức hợp chỉ với một dòng mã bằng cách sử dụng mô-đun

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
52

>>> document.getElementsByTagName("ellipse")
[
    <DOM Element: ellipse at 0x7fa2c944f430>,
    <DOM Element: ellipse at 0x7fa2c944f4c0>
]

>>> root = document.documentElement
>>> root.getElementsByTagName("ellipse")
[
    <DOM Element: ellipse at 0x7fa2c944f430>,
    <DOM Element: ellipse at 0x7fa2c944f4c0>
]
7

Miễn là quá trình phân tích cú pháp XML thành công, bạn có thể kiểm tra các thuộc tính thông thường của phần tử gốc, chẳng hạn như tên thẻ, thuộc tính, văn bản bên trong, v.v. Bạn sẽ có thể sử dụng toán tử dấu chấm để điều hướng sâu vào cây phần tử. Trong hầu hết các trường hợp, thư viện sẽ nhận dạng kiểu dữ liệu Python phù hợp và chuyển đổi giá trị cho bạn

Sau khi lưu những thay đổi đó và khởi động lại máy chủ, bạn sẽ cần tải lại trang trong trình duyệt web của mình để tạo kết nối WebSocket mới. Đây là một đầu ra mẫu của chương trình sửa đổi

>>> document.getElementsByTagName("ellipse")
[
    <DOM Element: ellipse at 0x7fa2c944f430>,
    <DOM Element: ellipse at 0x7fa2c944f4c0>
]

>>> root = document.documentElement
>>> root.getElementsByTagName("ellipse")
[
    <DOM Element: ellipse at 0x7fa2c944f430>,
    <DOM Element: ellipse at 0x7fa2c944f4c0>
]
8

Đôi khi, XML có thể chứa các tên thẻ không phải là mã định danh Python hợp lệ hoặc bạn có thể muốn điều chỉnh cấu trúc thông báo để phù hợp với mô hình dữ liệu của mình. Trong trường hợp như vậy, một tùy chọn thú vị sẽ là định nghĩa các lớp mô hình tùy chỉnh với các bộ mô tả khai báo cách tra cứu thông tin bằng các biểu thức XPath. Đó là phần bắt đầu giống với các mô hình Django hoặc định nghĩa lược đồ Pydantic

Bạn sẽ sử dụng một bộ mô tả

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
53 tùy chỉnh và một lớp
>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
54 đi kèm, cung cấp các thuộc tính có thể tái sử dụng cho các mô hình dữ liệu của bạn. Bộ mô tả mong đợi một biểu thức XPath để tra cứu phần tử trong thông báo đã nhận. Việc triển khai cơ bản hơi nâng cao, vì vậy vui lòng sao chép mã từ phần có thể thu gọn bên dưới

Bộ mô tả XPath và Lớp mô hìnhHiển thị/Ẩn

>>> document.getElementsByTagName("ellipse")
[
    <DOM Element: ellipse at 0x7fa2c944f430>,
    <DOM Element: ellipse at 0x7fa2c944f4c0>
]

>>> root = document.documentElement
>>> root.getElementsByTagName("ellipse")
[
    <DOM Element: ellipse at 0x7fa2c944f430>,
    <DOM Element: ellipse at 0x7fa2c944f4c0>
]
9

Giả sử bạn đã có bộ mô tả

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
53 mong muốn và lớp cơ sở trừu tượng
>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
54 trong mô-đun của mình, bạn có thể sử dụng chúng để xác định các loại thông báo
>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
47 và
>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
48 cùng với các khối xây dựng có thể tái sử dụng để tránh lặp lại. Có vô số cách để làm như vậy, nhưng đây là một ví dụ

>>> document.getElementsByTagNameNS(
..     "http://www.inkscape.org/namespaces/inkscape",
..     "custom"
.. )
...
[<DOM Element: inkscape:custom at 0x7f97e3f2a3a0>]

>>> document.getElementsByTagNameNS("*", "custom")
[<DOM Element: inkscape:custom at 0x7f97e3f2a3a0>]
0

Bộ mô tả

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
53 cho phép đánh giá chậm để các phần tử của thông báo XML chỉ được tra cứu khi được yêu cầu. Cụ thể hơn, chúng chỉ được tra cứu khi bạn truy cập một thuộc tính trên đối tượng sự kiện. Ngoài ra, các kết quả được lưu vào bộ đệm để tránh chạy cùng một truy vấn XPath nhiều lần. Bộ mô tả cũng tôn trọng các chú thích loại và tự động chuyển đổi dữ liệu được giải tuần tự hóa thành loại Python phù hợp

Việc sử dụng các đối tượng sự kiện đó không khác nhiều so với các đối tượng được tạo tự động bởi

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
52 trước đây

>>> document.getElementsByTagNameNS(
..     "http://www.inkscape.org/namespaces/inkscape",
..     "custom"
.. )
...
[<DOM Element: inkscape:custom at 0x7f97e3f2a3a0>]

>>> document.getElementsByTagNameNS("*", "custom")
[<DOM Element: inkscape:custom at 0x7f97e3f2a3a0>]
1

Có một bước bổ sung để tạo các đối tượng mới của loại sự kiện cụ thể. Nhưng ngoài ra, nó mang lại cho bạn sự linh hoạt hơn về mặt cấu trúc mô hình của bạn một cách độc lập với giao thức XML. Ngoài ra, có thể rút ra các thuộc tính mô hình mới dựa trên các thuộc tính trong tin nhắn đã nhận và thêm nhiều phương thức hơn vào đó

Tạo các mô hình từ một lược đồ XML

Triển khai các lớp mô hình là một nhiệm vụ tẻ nhạt và dễ xảy ra lỗi. Tuy nhiên, miễn là mô hình của bạn phản chiếu các thông báo XML, bạn có thể tận dụng lợi thế của một công cụ tự động để tạo mã cần thiết cho bạn dựa trên Lược đồ XML. Nhược điểm của mã như vậy là nó thường khó đọc hơn so với viết bằng tay

Một trong những mô-đun bên thứ ba lâu đời nhất cho phép điều đó là PyXB, bắt chước thư viện JAXB phổ biến của Java. Thật không may, nó đã được phát hành lần cuối cách đây vài năm và đang nhắm mục tiêu các phiên bản Python cũ. Bạn có thể xem xét một giải pháp thay thế

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
61 tương tự nhưng được duy trì tích cực, tạo ra các cấu trúc dữ liệu từ Lược đồ XML

Giả sử bạn có tệp lược đồ

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
62 này mô tả thông báo
>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
47 của bạn

>>> document.getElementsByTagNameNS(
..     "http://www.inkscape.org/namespaces/inkscape",
..     "custom"
.. )
...
[<DOM Element: inkscape:custom at 0x7f97e3f2a3a0>]

>>> document.getElementsByTagNameNS("*", "custom")
[<DOM Element: inkscape:custom at 0x7f97e3f2a3a0>]
2

Một lược đồ cho trình phân tích cú pháp XML biết những phần tử mong đợi, thứ tự và cấp độ của chúng trong cây. Nó cũng hạn chế các giá trị được phép cho các thuộc tính XML. Bất kỳ sự khác biệt nào giữa các khai báo này và một tài liệu XML thực tế sẽ khiến nó không hợp lệ và khiến trình phân tích cú pháp từ chối tài liệu

Ngoài ra, một số công cụ có thể tận dụng thông tin này để tạo ra một đoạn mã ẩn các chi tiết phân tích cú pháp XML khỏi bạn. Sau khi cài đặt thư viện, bạn sẽ có thể chạy lệnh

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
61 trong môi trường ảo đang hoạt động của mình

>>> document.getElementsByTagNameNS(
..     "http://www.inkscape.org/namespaces/inkscape",
..     "custom"
.. )
...
[<DOM Element: inkscape:custom at 0x7f97e3f2a3a0>]

>>> document.getElementsByTagNameNS("*", "custom")
[<DOM Element: inkscape:custom at 0x7f97e3f2a3a0>]
3

Nó sẽ tạo một tệp mới có tên

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
65 trong cùng thư mục với mã nguồn Python được tạo. Sau đó, bạn có thể nhập mô-đun đó và sử dụng nó để phân tích các thư đến

>>>

>>> document.getElementsByTagNameNS(
..     "http://www.inkscape.org/namespaces/inkscape",
..     "custom"
.. )
...
[<DOM Element: inkscape:custom at 0x7f97e3f2a3a0>]

>>> document.getElementsByTagNameNS("*", "custom")
[<DOM Element: inkscape:custom at 0x7f97e3f2a3a0>]
4

Nó trông tương tự như ví dụ

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
52 được hiển thị trước đó. Sự khác biệt là việc sử dụng liên kết dữ liệu sẽ thực thi việc tuân thủ lược đồ, trong khi
>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
52 tạo ra các đối tượng một cách linh hoạt bất kể chúng có đúng về mặt ngữ nghĩa hay không

Loại bỏ các quảng cáo

Gỡ bom XML bằng trình phân tích cú pháp an toàn

Trình phân tích cú pháp XML trong thư viện chuẩn của Python dễ bị tấn công bởi một loạt các mối đe dọa bảo mật có thể dẫn đến tấn công từ chối dịch vụ (DoS) hoặc mất dữ liệu. Đó không phải là lỗi của họ, công bằng mà nói. Chúng chỉ tuân theo đặc điểm kỹ thuật của tiêu chuẩn XML, phức tạp và mạnh mẽ hơn hầu hết mọi người biết

Ghi chú. Xin lưu ý rằng bạn nên sử dụng thông tin bạn sắp xem một cách khôn ngoan. Bạn không muốn trở thành kẻ tấn công, khiến bản thân phải chịu hậu quả pháp lý hoặc đối mặt với việc bị cấm sử dụng một dịch vụ cụ thể suốt đời

Một trong những kiểu tấn công phổ biến nhất là XML Bomb hay còn gọi là tấn công tỷ cười. Cuộc tấn công khai thác sự mở rộng thực thể trong DTD để làm nổ tung bộ nhớ và chiếm CPU càng lâu càng tốt. Tất cả những gì bạn cần để ngăn một máy chủ web không được bảo vệ nhận lưu lượng truy cập mới là một vài dòng mã XML này

>>> document.getElementsByTagNameNS(
..     "http://www.inkscape.org/namespaces/inkscape",
..     "custom"
.. )
...
[<DOM Element: inkscape:custom at 0x7f97e3f2a3a0>]

>>> document.getElementsByTagNameNS("*", "custom")
[<DOM Element: inkscape:custom at 0x7f97e3f2a3a0>]
5

Trình phân tích cú pháp ngây thơ sẽ cố gắng giải quyết thực thể tùy chỉnh

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
68 được đặt trong thư mục gốc của tài liệu bằng cách kiểm tra DTD. Tuy nhiên, bản thân thực thể đó đề cập đến một thực thể khác nhiều lần, thực thể này lại đề cập đến một thực thể khác, v.v. Khi chạy đoạn mã trên, bạn sẽ nhận thấy có điều gì đó đáng lo ngại về bộ nhớ và bộ xử lý của mình

Hãy xem bộ nhớ chính và phân vùng trao đổi cạn kiệt chỉ trong vài giây trong khi một trong các CPU hoạt động với 100% công suất. Quá trình ghi dừng đột ngột khi bộ nhớ hệ thống đầy và sau đó tiếp tục sau khi quá trình Python bị hủy

Một kiểu tấn công phổ biến khác được gọi là XXE lợi dụng các thực thể chung bên ngoài để đọc các tệp cục bộ và thực hiện các yêu cầu mạng. Tuy nhiên, bắt đầu từ Python 3. 7. 1, tính năng này đã bị tắt theo mặc định để tăng tính bảo mật. Nếu bạn tin tưởng dữ liệu của mình thì bạn vẫn có thể yêu cầu trình phân tích cú pháp SAX xử lý các thực thể bên ngoài

>>>

>>> document.getElementsByTagNameNS(
..     "http://www.inkscape.org/namespaces/inkscape",
..     "custom"
.. )
...
[<DOM Element: inkscape:custom at 0x7f97e3f2a3a0>]

>>> document.getElementsByTagNameNS("*", "custom")
[<DOM Element: inkscape:custom at 0x7f97e3f2a3a0>]
6

Trình phân tích cú pháp này sẽ có thể đọc các tệp cục bộ trên máy tính của bạn. Ví dụ, nó có thể lấy tên người dùng trên hệ điều hành giống Unix

>>>

>>> document.getElementsByTagNameNS(
..     "http://www.inkscape.org/namespaces/inkscape",
..     "custom"
.. )
...
[<DOM Element: inkscape:custom at 0x7f97e3f2a3a0>]

>>> document.getElementsByTagNameNS("*", "custom")
[<DOM Element: inkscape:custom at 0x7f97e3f2a3a0>]
7

Việc gửi dữ liệu đó qua mạng đến một máy chủ từ xa là hoàn toàn khả thi

Bây giờ, làm thế nào bạn có thể tự bảo vệ mình khỏi các cuộc tấn công như vậy? . Mặc dù không được phân phối với Python, nhưng

>>> document = parse("smiley.svg")

>>> # XML Declaration
>>> document.version, document.encoding, document.standalone
('1.0', 'UTF-8', False)

>>> # Document Type Definition (DTD)
>>> dtd = document.doctype
>>> dtd.entities["custom_entity"].childNodes
[<DOM Text node "'Hello'">]

>>> # Document Root
>>> document.documentElement
<DOM Element: svg at 0x7fc78c62d790>
69 là một sự thay thế thả vào cho tất cả các trình phân tích cú pháp trong thư viện chuẩn

Thư viện áp đặt các giới hạn nghiêm ngặt và vô hiệu hóa rất nhiều tính năng XML nguy hiểm. Nó sẽ ngăn chặn hầu hết các cuộc tấn công nổi tiếng, bao gồm cả hai cuộc tấn công vừa được mô tả. Để sử dụng nó, hãy lấy thư viện từ PyPI và thay thế các câu lệnh nhập của bạn cho phù hợp

>>>

>>> document.getElementsByTagNameNS(
..     "http://www.inkscape.org/namespaces/inkscape",
..     "custom"
.. )
...
[<DOM Element: inkscape:custom at 0x7f97e3f2a3a0>]

>>> document.getElementsByTagNameNS("*", "custom")
[<DOM Element: inkscape:custom at 0x7f97e3f2a3a0>]
8

Đó là nó. Các tính năng bị cấm sẽ không hoạt động nữa

Phần kết luận

Định dạng dữ liệu XML là một tiêu chuẩn trưởng thành và mạnh mẽ đáng ngạc nhiên vẫn còn được sử dụng cho đến ngày nay, đặc biệt là trong môi trường doanh nghiệp. Chọn đúng trình phân tích cú pháp XML là rất quan trọng trong việc tìm ra điểm phù hợp giữa hiệu suất, bảo mật, tuân thủ và tiện lợi

Hướng dẫn này cung cấp cho bạn một lộ trình chi tiết để điều hướng mê cung khó hiểu của các trình phân tích cú pháp XML trong Python. Bạn biết đi đường tắt ở đâu và làm thế nào để tránh ngõ cụt, giúp bạn tiết kiệm rất nhiều thời gian

Trong hướng dẫn này, bạn đã học cách

  • Chọn mô hình phân tích cú pháp XML phù hợp
  • Sử dụng các trình phân tích cú pháp XML trong thư viện chuẩn
  • Sử dụng các thư viện phân tích cú pháp XML chính
  • Phân tích tài liệu XML một cách khai báo bằng cách sử dụng liên kết dữ liệu
  • Sử dụng các trình phân tích cú pháp XML an toàn để loại bỏ các lỗ hổng bảo mật

Bây giờ, bạn đã hiểu các chiến lược khác nhau để phân tích cú pháp tài liệu XML cũng như điểm mạnh và điểm yếu của chúng. Với kiến ​​thức này, bạn có thể chọn trình phân tích cú pháp XML phù hợp nhất cho trường hợp sử dụng cụ thể của mình và thậm chí kết hợp nhiều trình phân tích cú pháp để đọc các tệp XML nhiều gigabyte nhanh hơn

Đánh dấu là đã hoàn thành

🐍 Thủ thuật Python 💌

Nhận một Thủ thuật Python ngắn và hấp dẫn được gửi đến hộp thư đến của bạn vài ngày một lần. Không có thư rác bao giờ. Hủy đăng ký bất cứ lúc nào. Được quản lý bởi nhóm Real Python

Chuyển đổi XML thành đối tượng Python

Gửi cho tôi thủ thuật Python »

Giới thiệu về Bartosz Zaczyński

Chuyển đổi XML thành đối tượng Python
Chuyển đổi XML thành đối tượng Python

Bartosz là người hướng dẫn bootcamp, tác giả và lập trình viên đa ngôn ngữ yêu thích Python. Anh ấy giúp sinh viên của mình tiếp cận công nghệ phần mềm bằng cách chia sẻ kinh nghiệm thương mại hơn một thập kỷ trong ngành CNTT

» Thông tin thêm về Bartosz


Mỗi hướng dẫn tại Real Python được tạo bởi một nhóm các nhà phát triển để nó đáp ứng các tiêu chuẩn chất lượng cao của chúng tôi. Các thành viên trong nhóm đã làm việc trong hướng dẫn này là

Chuyển đổi XML thành đối tượng Python

Aldren

Chuyển đổi XML thành đối tượng Python

David

Chuyển đổi XML thành đối tượng Python

Geir Arne

Chuyển đổi XML thành đối tượng Python

Sadie

Bậc thầy Kỹ năng Python trong thế giới thực Với quyền truy cập không giới hạn vào Python thực

Tham gia với chúng tôi và có quyền truy cập vào hàng nghìn hướng dẫn, khóa học video thực hành và cộng đồng các Pythonistas chuyên gia

Nâng cao kỹ năng Python của bạn »

Chuyên gia Kỹ năng Python trong thế giới thực
Với quyền truy cập không giới hạn vào Python thực

Tham gia với chúng tôi và có quyền truy cập vào hàng ngàn hướng dẫn, khóa học video thực hành và cộng đồng Pythonistas chuyên gia

Nâng cao kỹ năng Python của bạn »

Bạn nghĩ sao?

Đánh giá bài viết này

Tweet Chia sẻ Chia sẻ Email

Bài học số 1 hoặc điều yêu thích mà bạn đã học được là gì?

Mẹo bình luận. Những nhận xét hữu ích nhất là những nhận xét được viết với mục đích học hỏi hoặc giúp đỡ các sinh viên khác. và nhận câu trả lời cho các câu hỏi phổ biến trong cổng thông tin hỗ trợ của chúng tôi

Làm cách nào để chuyển đổi tệp XML sang Python?

Cách chuyển đổi XML sang CSV trong Python – Hướng dẫn từng bước .
Phân tích tệp XML
Tạo một CSV mới
Thêm tiêu đề vào tệp CSV, với các trường cần được đưa vào
Đối với mỗi phần tử xml, hãy trích xuất các trường có liên quan và thêm hàng mới vào tệp CSV

Làm cách nào để chuyển đổi XML thành dict trong Python?

Sử dụng xmltodict. parse() để phân tích cú pháp nội dung từ biến và chuyển nó thành Từ điển .

Bạn có thể chuyển đổi XML thành JSON bằng Python không?

Sử dụng Mô-đun xmltodict. Xmltodict là một mô-đun Python phổ biến có thể chuyển đổi cấu trúc XML của bạn thành cấu trúc JSON . Nó giúp làm việc trong XML Dễ dàng để bạn có cảm giác như đang làm việc với JSON. Nó không phải là một mô-đun được xác định trước và do đó bạn cần cài đặt nó bằng lệnh cài đặt pip.

Làm cách nào để phân tích cú pháp dữ liệu XML trong Python?

Để phân tích cú pháp tài liệu XML, bạn cần có toàn bộ tài liệu trong bộ nhớ. .
Để phân tích cú pháp tài liệu XML
Nhập xml. nhà thờ. thiểu số
Sử dụng hàm “parse” để phân tích tài liệu ( doc=xml. nhà thờ. thiểu số. phân tích cú pháp (tên tệp);
Gọi danh sách các thẻ XML từ tài liệu XML bằng mã (=doc. getElementsByTagName(“tên của thẻ xml”)