CFSDN nhấn mạnh vào việc tạo ra giá trị thông qua mã nguồn mở. Chúng tôi cam kết xây dựng một nền tảng chia sẻ tài nguyên để mọi người làm CNTT có thể tìm thấy thế giới tuyệt vời của riêng mình tại đây.
Bài đăng trên blog CFSDN này sẽ đưa bạn đi sâu hơn vào các công cụ XML trong Python. Bài đăng được biên soạn bởi tác giả. Nếu bạn quan tâm đến bài viết này, vui lòng cho nó một lượt thích.
Mô-đun: xmllib.
xmllib là trình phân tích cú pháp cấp thấp, không xác thực. Các lập trình viên ứng dụng sử dụng xmllib có thể ghi đè lớp XMLParser và cung cấp các phương thức để xử lý các thành phần tài liệu như thẻ cụ thể hoặc chung chung hoặc các thực thể ký tự. Việc sử dụng xmllib không thay đổi từ Python 1.5x sang Python 2.0+; trong hầu hết các trường hợp, tốt hơn là sử dụng công nghệ SAX, đây cũng là công nghệ hướng luồng và chuẩn hơn cho các ngôn ngữ và nhà phát triển.
Các ví dụ trong bài viết này giống như trong cột gốc: chúng bao gồm một DTD có tên là quotations.dtd và tài liệu sample.xml cho DTD này (xem phần Tài nguyên để biết kho lưu trữ các tệp được đề cập trong bài viết này). Đoạn mã sau hiển thị một vài dòng đầu tiên của mỗi đoạn văn trong sample.xml và tạo ra các chỉ báo ASCII rất đơn giản cho các thẻ và thực thể không xác định. Văn bản đã phân tích cú pháp được xử lý như một luồng liên tục và bất kỳ bộ tích lũy nào được sử dụng đều là trách nhiệm của lập trình viên (chẳng hạn như chuỗi trong thẻ (#PCDATA) hoặc danh sách hoặc từ điển các thẻ gặp phải). Liệt kê 1: try_xmllib.py.
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
hai mươi mốt
hai mươi hai
hai mươi ba
hai mươi bốn
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
nhập khẩu
xmllib, chuỗi
lớpQuotationParser
(xmllib.XMLParser):
định nghĩa__init__
(
bản thân
):
xmllib.XMLParser.__init__(
bản thân
)
bản thân
.trích dẫn này
=
''
xử lý dữ liệu
(
bản thân
, dữ liệu):
bản thân
.trích dẫn này
=
bản thân
.trích dẫn này
+
dữ liệu
lỗi cú pháp
(
bản thân
, tin nhắn):
vượt qua
defstart_quotations
(
bản thân
, thuộc tính):
in
'--- Bắt đầu tài liệu ---'
defstart_quotation
(
bản thân
, thuộc tính):
in
'TRÍCH DẪN:'
bảo vệ_trích dẫn
(
bản thân
):
in
chuỗi.join(chuỗi.split(
bản thân
.trích dẫn này[:
230
]))
+
'...'
,
in
'('
+
đường
(
len
(
bản thân
.trích dẫn này))
+
'byte)\n'
bản thân
.trích dẫn này
=
''
defunknown_starttag
(
bản thân
, thẻ, thuộc tính):
bản thân
.trích dẫn này
=
bản thân
.trích dẫn này
+
'{'
defunknown_endtag
(
bản thân
, nhãn):
bản thân
.trích dẫn này
=
bản thân
.trích dẫn này
+
'}'
defunknown_charref
(
bản thân
, tham khảo):
bản thân
.trích dẫn này
=
bản thân
.trích dẫn này
+
'?'
defunknown_entityref
(
bản thân
, tham khảo):
bản thân
.trích dẫn này
=
bản thân
.trích dẫn này
+
'#'
nếu như
__tên__
=
=
'__chủ yếu__'
:
bộ phân tích cú pháp
=
Trình phân tích trích dẫn()
vì
c
TRONG
mở
(
"mẫu.xml"
).đọc():
trình phân tích cú pháp.feed(c)
trình phân tích cú pháp.đóng()
|
xác minh.
Lý do bạn có thể muốn hướng đến tương lai của hỗ trợ XML chuẩn là vì bạn cần thực hiện xác thực cùng lúc với phân tích cú pháp. Thật không may, gói XML Python 2.0 chuẩn không bao gồm trình phân tích cú pháp xác thực.
xmlproc là trình phân tích cú pháp gốc của python, thực hiện xác thực gần như hoàn chỉnh. Nếu bạn cần một trình phân tích xác thực, xmlproc hiện là lựa chọn duy nhất của bạn cho Python. Hơn nữa, xmlproc cung cấp nhiều giao diện thử nghiệm và nâng cao không có trong các trình phân tích cú pháp khác.
Chọn một trình phân tích cú pháp.
Nếu bạn quyết định sử dụng Simple API for XML (SAX) -- API này nên được sử dụng cho những thứ phức tạp vì hầu hết các công cụ khác đều được xây dựng dựa trên API này -- thì phần lớn công việc phân loại trình phân tích cú pháp sẽ được thực hiện thay bạn. Mô-đun xml.sax có chức năng tự động chọn trình phân tích cú pháp "tốt nhất". Trong cài đặt Python 2.0 chuẩn, trình phân tích cú pháp duy nhất bạn có thể chọn là expat, một tiện ích mở rộng nhanh được viết bằng C. Tuy nhiên, bạn có thể cài đặt trình phân tích cú pháp khác trong $PYTHONLIB/xml/parsers làm giải pháp thay thế. Việc thiết lập trình phân tích cú pháp rất đơn giản: Liệt kê 2: Câu lệnh của Python để chọn trình phân tích cú pháp tốt nhất.
?
1
2
3
|
nhập khẩu
xml. sax
bộ phân tích cú pháp
=
xml.sax.make_parser()
|
Bạn cũng có thể truyền đối số để chọn một trình phân tích cú pháp cụ thể; nhưng vì lý do khả năng di động -- và để tương thích tốt hơn với các trình phân tích cú pháp tốt hơn trong tương lai -- cách tiếp cận tốt nhất là sử dụng make_parser() để thực hiện công việc.
Bạn có thể nhập trực tiếp xml.parsers.expat. Nếu bạn làm như vậy, bạn sẽ có thể sử dụng một số thủ thuật đặc biệt mà giao diện SAX không cung cấp. Do đó, xml.parsers.expat có phần "cấp thấp" hơn so với SAX. Nhưng công nghệ SAX rất chuẩn và xử lý định hướng luồng rất tốt; trong hầu hết các trường hợp, SAX là mức phù hợp. Thông thường, sự khác biệt về tốc độ thực tế là nhỏ vì hàm make_parser() đã có được hiệu suất do expat cung cấp.
SAX là gì?
Với bối cảnh như vậy, câu trả lời tốt hơn cho câu hỏi SAX là gì là:
SAX (Simple API for XML) là giao diện phân tích cú pháp phổ biến cho các trình phân tích cú pháp XML. Nó cho phép tác giả ứng dụng viết các ứng dụng sử dụng trình phân tích cú pháp XML nhưng vẫn độc lập với trình phân tích cú pháp được sử dụng. (Hãy nghĩ về nó như JDBC dành cho XML.) (Lars Marius Garshol, SAX dành cho Python).
SAX -- giống như API mà nó cung cấp cho các mô-đun phân tích cú pháp -- về cơ bản là một bộ xử lý tuần tự các tài liệu XML. Cách sử dụng rất giống với ví dụ xmllib, nhưng trừu tượng hơn. Thay vì lớp trình phân tích cú pháp, lập trình viên ứng dụng định nghĩa một lớp xử lý có thể được đăng ký với bất kỳ trình phân tích cú pháp nào được sử dụng. Bốn giao diện SAX (mỗi giao diện có một số phương thức) phải được xác định: DocumentHandler, DTDHandler, EntityResolver và ErrorHandler. Khi tạo trình phân tích cú pháp, nó cũng kết nối với giao diện mặc định trừ khi bị ghi đè. Mã này thực hiện các nhiệm vụ giống như ví dụ xmllib: Liệt kê 3: try_sax.py .
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
hai mươi mốt
hai mươi hai
hai mươi ba
hai mươi bốn
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
"Ví dụ SAX đơn giản, được cập nhật cho Python 2.0 trở lên"
nhập khẩu
sợi dây
nhập khẩu
xml. sax
từ
xml.sax.handler
nhập khẩu
*
lớpQuotationHandler
(Trình xử lý nội dung):
định nghĩa__init__
(
bản thân
):
bản thân
. trong trích dẫn
=
0
bản thân
.trích dẫn này
=
''
defstartTài liệu
(
bản thân
):
in
'--- Bắt đầu tài liệu ---'
phần tử defstart
(
bản thân
, tên, thuộc tính):
nếu như
tên
=
=
'Trích dẫn'
:
in
'TRÍCH DẪN:'
bản thân
. trong trích dẫn
=
1
khác
:
bản thân
.trích dẫn này
=
bản thân
.trích dẫn này
+
'{'
bảo vệ phần tử
(
bản thân
, tên):
nếu như
tên
=
=
'Trích dẫn'
:
in
chuỗi.join(chuỗi.split(
bản thân
.trích dẫn này[:
230
]))
+
'...'
,
in
'('
+
đường
(
len
(
bản thân
.trích dẫn này))
+
'byte)\n'
bản thân
.trích dẫn này
=
''
bản thân
. trong trích dẫn
=
0
khác
:
bản thân
.trích dẫn này
=
bản thân
.trích dẫn này
+
'}'
định nghĩa ký tự
(
bản thân
, ch):
nếu như
bản thân
.in_quote:
bản thân
.trích dẫn này
=
bản thân
.trích dẫn này
+
ch
nếu như
__tên__
=
=
'__chủ yếu__'
:
bộ phân tích cú pháp
=
xml.sax.make_parser()
người xử lý
=
Trình xử lý trích dẫn()
parser.setContentHandler(trình xử lý)
parser.parse(
"mẫu.xml"
)
|
Có hai điểm nhỏ cần lưu ý trong ví dụ trên so với xmllib: phương thức .parse() xử lý toàn bộ luồng hoặc chuỗi, do đó không cần tạo vòng lặp cho trình phân tích cú pháp; và .parse() cũng đủ linh hoạt để chấp nhận tên tệp, đối tượng tệp hoặc nhiều đối tượng giống tệp (một số có phương thức .read()).
Gói: DOM.
DOM là dạng biểu diễn cây cấp cao của một tài liệu XML. Mô hình này không dành riêng cho Python mà là mô hình XML chung (xem phần Tài nguyên để biết thêm thông tin). Gói DOM của Python được xây dựng dựa trên SAX và được bao gồm trong hỗ trợ XML chuẩn trong Python 2.0. Do giới hạn về không gian, tôi không đưa các ví dụ mã vào bài viết này, nhưng có một mô tả chung tuyệt vời được đưa ra trong "Python/XML HOWTO" của XML-SIG:
Mô hình đối tượng tài liệu chỉ định cách biểu diễn cây cho các tài liệu XML. Thể hiện tài liệu cấp cao nhất là gốc của cây và chỉ có một nút con, thể hiện phần tử cấp cao nhất; phần tử này có các nút con biểu diễn nội dung và các phần tử con, các phần tử này cũng có thể có các nút con, v.v. Các hàm được xác định cho phép duyệt tùy ý cây kết quả, truy cập các giá trị phần tử và thuộc tính, chèn và xóa các nút, và chuyển đổi cây trở lại thành XML.
DOM có thể được sử dụng để sửa đổi các tài liệu XML vì bạn có thể tạo cây DOM, sửa đổi cây bằng cách thêm các nút mới và di chuyển các cây con xung quanh, sau đó tạo một tài liệu XML mới làm đầu ra. Bạn cũng có thể tự xây dựng cây DOM rồi chuyển đổi nó sang XML; phương pháp tạo đầu ra XML này linh hoạt hơn so với việc chỉ ghi ... vào một tệp.
Cú pháp sử dụng mô-đun xml.dom đã thay đổi đôi chút so với các bài viết trước. Việc triển khai DOM đi kèm với Python 2.0 được gọi là xml.dom.minidom và cung cấp phiên bản DOM nhẹ và nhỏ. Rõ ràng là có một số tính năng thử nghiệm từ XML-SIG DOM đầy đủ không được đưa vào xml.dom.minidom, nhưng không ai để ý đến điều đó.
Việc tạo một đối tượng DOM rất dễ dàng; chỉ cần: Liệt kê 4: Tạo một đối tượng DOM Python trong tệp XML.
?
1
2
3
4
5
6
7
8
9
|
từ
xml.dom.minidom
nhập khẩu
phân tích cú pháp, phân tích cú phápString
dom1
=
phân tích(
'mydata.xml'
)
|
Làm việc với các đối tượng DOM là công việc theo phong cách OOP khá đơn giản. Tuy nhiên, chúng ta thường gặp nhiều thuộc tính giống danh sách trong một hệ thống phân cấp mà không thể dễ dàng phân biệt ngay lập tức (trừ trường hợp liệt kê vòng tròn). Ví dụ, đây là đoạn mã DOM Python phổ biến: Liệt kê 5: Lặp qua các đối tượng nút DOM của Python.
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
hai mươi mốt
hai mươi hai
hai mươi ba
|
vì
nút
TRONG
dom_node.childNodes:
nếu như
node.tên_node
=
=
'#chữ'
:
DỮ LIỆU PC
=
node.giá trị node
nếu
node.tên_node
=
=
'thư rác'
:
spam_node_list.append(nút)
|
Tài liệu chuẩn của Python có một số ví dụ DOM chi tiết hơn. Các ví dụ trong bài viết trước của tôi (xem phần Tài nguyên) về cách sử dụng các đối tượng DOM vẫn đúng hướng, nhưng một số tên phương thức và thuộc tính đã thay đổi kể từ khi bài viết được xuất bản, vì vậy hãy kiểm tra tài liệu Python.
Mô-đun: pyxie.
Mô-đun pyxie được xây dựng dựa trên hỗ trợ XML chuẩn của Python và cung cấp thêm các giao diện cấp cao cho các tài liệu XML. pyxie thực hiện hai nhiệm vụ cơ bản: chuyển đổi tài liệu XML sang định dạng dựa trên dòng dễ phân tích cú pháp hơn; và cung cấp các phương pháp để thao tác tài liệu XML dưới dạng cây có thể thao tác được. Định dạng PYX dựa trên dòng được pyxie sử dụng không phụ thuộc vào ngôn ngữ và có sẵn các công cụ cho nhiều ngôn ngữ. Nhìn chung, việc biểu diễn tài liệu bằng PYX dễ xử lý hơn so với việc biểu diễn XML bằng các công cụ xử lý văn bản dựa trên dòng thông thường như grep, sed, awk, bash, perl hoặc các mô-đun python chuẩn như string và re. Tùy thuộc vào kết quả, việc chuyển từ XML sang PYX có thể tiết kiệm được rất nhiều công sức.
Khái niệm pyxie xử lý tài liệu XML như cây tương tự như ý tưởng trong DOM. Vì chuẩn DOM được hỗ trợ rộng rãi bởi nhiều ngôn ngữ lập trình nên hầu hết các lập trình viên sẽ sử dụng chuẩn DOM thay vì pyxie nếu cần biểu diễn dạng cây của tài liệu XML.
Thêm các mô-đun: xml_pickle và xml_objectify.
Tôi đã phát triển các mô-đun cấp cao của riêng mình để xử lý XML, được gọi là xml_pickle và xml_objectify. Tôi đã viết nhiều mô-đun tương tự ở nơi khác (xem phần Tài nguyên), vì vậy tôi sẽ không đi sâu vào chi tiết ở đây. Các mô-đun này rất hữu ích khi bạn "suy nghĩ bằng Python" thay vì "suy nghĩ bằng XML". Đặc biệt, xml_objectify ẩn hầu như mọi manh mối XML khỏi lập trình viên, cho phép bạn sử dụng đầy đủ các đối tượng "thô" của Python trong chương trình của mình. Định dạng dữ liệu XML thực tế được trừu tượng hóa đến mức gần như vô hình. Tương tự như vậy, xml_pickle cho phép các lập trình viên Python bắt đầu với các đối tượng Python "thô" có dữ liệu có thể đến từ bất kỳ mã nguồn nào, sau đó (liên tục) đưa chúng vào định dạng XML mà người dùng khác có thể cần sau này.
Cuối cùng, bài viết này về hiểu biết sâu hơn về các công cụ XML trong Python đã kết thúc tại đây. Nếu bạn muốn biết thêm về hiểu biết sâu hơn về các công cụ XML trong Python, vui lòng tìm kiếm các bài viết CFSDN hoặc tiếp tục duyệt các bài viết liên quan. Tôi hy vọng bạn sẽ ủng hộ blog của tôi trong tương lai! .
Tôi là một lập trình viên xuất sắc, rất giỏi!