Python - Xử lý XML
XML là một ngôn ngữ mã nguồn mở, di động cho phép các lập trình viên phát triển các ứng dụng mà các ứng dụng khác có thể đọc được, bất kể hệ điều hành và / hoặc ngôn ngữ phát triển.
XML là gì?
Ngôn ngữ đánh dấu mở rộng (XML) là một ngôn ngữ đánh dấu giống như HTML hoặc SGML. Điều này được khuyến nghị bởi World Wide Web Consortium và có sẵn như một tiêu chuẩn mở.
XML cực kỳ hữu ích để theo dõi lượng dữ liệu vừa và nhỏ mà không yêu cầu xương sống dựa trên SQL.
Kiến trúc phân tích cú pháp XML và API
Thư viện chuẩn Python cung cấp một bộ giao diện tối thiểu nhưng hữu ích để làm việc với XML.
Hai API cơ bản và được sử dụng rộng rãi nhất cho dữ liệu XML là giao diện SAX và DOM.
Simple API for XML (SAX)- Tại đây, bạn đăng ký các lệnh gọi lại cho các sự kiện quan tâm và sau đó để trình phân tích cú pháp tiến hành thông qua tài liệu. Điều này hữu ích khi tài liệu của bạn lớn hoặc bạn có giới hạn về bộ nhớ, nó phân tích cú pháp tệp khi nó đọc từ đĩa và toàn bộ tệp không bao giờ được lưu trữ trong bộ nhớ.
Document Object Model (DOM) API - Đây là khuyến nghị của World Wide Web Consortium trong đó toàn bộ tệp được đọc vào bộ nhớ và được lưu trữ ở dạng phân cấp (dựa trên cây) để thể hiện tất cả các tính năng của tài liệu XML.
SAX rõ ràng không thể xử lý thông tin nhanh như DOM có thể khi làm việc với các tệp lớn. Mặt khác, việc sử dụng riêng DOM thực sự có thể giết chết tài nguyên của bạn, đặc biệt nếu được sử dụng trên nhiều tệp nhỏ.
SAX ở chế độ chỉ đọc, trong khi DOM cho phép thay đổi tệp XML. Vì hai API khác nhau này bổ sung cho nhau theo nghĩa đen, nên không có lý do gì bạn không thể sử dụng cả hai cho các dự án lớn.
Đối với tất cả các ví dụ về mã XML của chúng tôi, hãy sử dụng tệp XML đơn giản movies.xml làm đầu vào -
<collection shelf="New Arrivals">
<movie title="Enemy Behind">
<type>War, Thriller</type>
<format>DVD</format>
<year>2003</year>
<rating>PG</rating>
<stars>10</stars>
<description>Talk about a US-Japan war</description>
</movie>
<movie title="Transformers">
<type>Anime, Science Fiction</type>
<format>DVD</format>
<year>1989</year>
<rating>R</rating>
<stars>8</stars>
<description>A schientific fiction</description>
</movie>
<movie title="Trigun">
<type>Anime, Action</type>
<format>DVD</format>
<episodes>4</episodes>
<rating>PG</rating>
<stars>10</stars>
<description>Vash the Stampede!</description>
</movie>
<movie title="Ishtar">
<type>Comedy</type>
<format>VHS</format>
<rating>PG</rating>
<stars>2</stars>
<description>Viewable boredom</description>
</movie>
</collection>
Phân tích cú pháp XML với các API SAX
SAX là một giao diện tiêu chuẩn để phân tích cú pháp XML theo hướng sự kiện. Phân tích cú pháp XML với SAX thường yêu cầu bạn tạo ContentHandler của riêng mình bằng cách phân lớp xml.sax.ContentHandler.
ContentHandler của bạn xử lý các thẻ và thuộc tính cụ thể của (các) hương vị XML của bạn. Đối tượng ContentHandler cung cấp các phương thức để xử lý các sự kiện phân tích cú pháp khác nhau. Bộ phân tích cú pháp riêng của nó gọi các phương thức ContentHandler vì nó phân tích cú pháp tệp XML.
Các phương thức startDocument và endDocument được gọi ở phần đầu và phần cuối của tệp XML. Các ký tự phương thức (văn bản) được truyền dữ liệu ký tự của tệp XML thông qua văn bản tham số.
ContentHandler được gọi ở đầu và cuối mỗi phần tử. Nếu trình phân tích cú pháp không ở chế độ không gian tên, các phương thức startElement (thẻ, thuộc tính) và endElement (thẻ) được gọi; nếu không, các phương thức tương ứng startElementNS và endElementNS được gọi. Ở đây, thẻ là thẻ phần tử và các thuộc tính là một đối tượng Thuộc tính.
Dưới đây là các phương pháp quan trọng khác cần hiểu trước khi tiếp tục -
Các make_parser Phương pháp
Phương thức sau tạo một đối tượng phân tích cú pháp mới và trả về nó. Đối tượng phân tích cú pháp được tạo sẽ thuộc loại trình phân tích cú pháp đầu tiên mà hệ thống tìm thấy.
xml.sax.make_parser( [parser_list] )
Đây là chi tiết của các thông số -
parser_list - Đối số tùy chọn bao gồm danh sách các trình phân tích cú pháp để sử dụng, tất cả các trình này đều phải triển khai phương thức make_parser.
Các phân tích Phương pháp
Phương thức sau tạo một trình phân tích cú pháp SAX và sử dụng nó để phân tích cú pháp tài liệu.
xml.sax.parse( xmlfile, contenthandler[, errorhandler])
Đây là chi tiết của các thông số -
xmlfile - Đây là tên của tệp XML cần đọc.
contenthandler - Đây phải là một đối tượng ContentHandler.
errorhandler - Nếu được chỉ định, trình xử lý lỗi phải là một đối tượng SAX ErrorHandler.
Các parseString Phương pháp
Có một phương pháp nữa để tạo trình phân tích cú pháp SAX và phân tích cú pháp được chỉ định XML string.
xml.sax.parseString(xmlstring, contenthandler[, errorhandler])
Đây là chi tiết của các thông số -
xmlstring - Đây là tên của chuỗi XML cần đọc.
contenthandler - Đây phải là một đối tượng ContentHandler.
errorhandler - Nếu được chỉ định, trình xử lý lỗi phải là một đối tượng SAX ErrorHandler.
Thí dụ
#!/usr/bin/python
import xml.sax
class MovieHandler( xml.sax.ContentHandler ):
def __init__(self):
self.CurrentData = ""
self.type = ""
self.format = ""
self.year = ""
self.rating = ""
self.stars = ""
self.description = ""
# Call when an element starts
def startElement(self, tag, attributes):
self.CurrentData = tag
if tag == "movie":
print "*****Movie*****"
title = attributes["title"]
print "Title:", title
# Call when an elements ends
def endElement(self, tag):
if self.CurrentData == "type":
print "Type:", self.type
elif self.CurrentData == "format":
print "Format:", self.format
elif self.CurrentData == "year":
print "Year:", self.year
elif self.CurrentData == "rating":
print "Rating:", self.rating
elif self.CurrentData == "stars":
print "Stars:", self.stars
elif self.CurrentData == "description":
print "Description:", self.description
self.CurrentData = ""
# Call when a character is read
def characters(self, content):
if self.CurrentData == "type":
self.type = content
elif self.CurrentData == "format":
self.format = content
elif self.CurrentData == "year":
self.year = content
elif self.CurrentData == "rating":
self.rating = content
elif self.CurrentData == "stars":
self.stars = content
elif self.CurrentData == "description":
self.description = content
if ( __name__ == "__main__"):
# create an XMLReader
parser = xml.sax.make_parser()
# turn off namepsaces
parser.setFeature(xml.sax.handler.feature_namespaces, 0)
# override the default ContextHandler
Handler = MovieHandler()
parser.setContentHandler( Handler )
parser.parse("movies.xml")
Điều này sẽ tạo ra kết quả sau:
*****Movie*****
Title: Enemy Behind
Type: War, Thriller
Format: DVD
Year: 2003
Rating: PG
Stars: 10
Description: Talk about a US-Japan war
*****Movie*****
Title: Transformers
Type: Anime, Science Fiction
Format: DVD
Year: 1989
Rating: R
Stars: 8
Description: A schientific fiction
*****Movie*****
Title: Trigun
Type: Anime, Action
Format: DVD
Rating: PG
Stars: 10
Description: Vash the Stampede!
*****Movie*****
Title: Ishtar
Type: Comedy
Format: VHS
Rating: PG
Stars: 2
Description: Viewable boredom
Để biết chi tiết đầy đủ về tài liệu SAX API, vui lòng tham khảo các API SAX Python tiêu chuẩn .
Phân tích cú pháp XML với các API DOM
Mô hình Đối tượng Tài liệu ("DOM") là một API đa ngôn ngữ từ World Wide Web Consortium (W3C) để truy cập và sửa đổi các tài liệu XML.
DOM cực kỳ hữu ích cho các ứng dụng truy cập ngẫu nhiên. SAX chỉ cho phép bạn xem từng bit của tài liệu tại một thời điểm. Nếu bạn đang xem xét một phần tử SAX, bạn không có quyền truy cập vào phần tử khác.
Đây là cách dễ nhất để tải nhanh một tài liệu XML và tạo một đối tượng minidom bằng cách sử dụng mô-đun xml.dom. Đối tượng minidom cung cấp một phương thức phân tích cú pháp đơn giản để nhanh chóng tạo một cây DOM từ tệp XML.
Cụm từ mẫu gọi hàm phân tích cú pháp (tệp [, trình phân tích cú pháp]) của đối tượng minidom để phân tích cú pháp tệp XML được chỉ định bởi tệp thành đối tượng cây DOM.
#!/usr/bin/python
from xml.dom.minidom import parse
import xml.dom.minidom
# Open XML document using minidom parser
DOMTree = xml.dom.minidom.parse("movies.xml")
collection = DOMTree.documentElement
if collection.hasAttribute("shelf"):
print "Root element : %s" % collection.getAttribute("shelf")
# Get all the movies in the collection
movies = collection.getElementsByTagName("movie")
# Print detail of each movie.
for movie in movies:
print "*****Movie*****"
if movie.hasAttribute("title"):
print "Title: %s" % movie.getAttribute("title")
type = movie.getElementsByTagName('type')[0]
print "Type: %s" % type.childNodes[0].data
format = movie.getElementsByTagName('format')[0]
print "Format: %s" % format.childNodes[0].data
rating = movie.getElementsByTagName('rating')[0]
print "Rating: %s" % rating.childNodes[0].data
description = movie.getElementsByTagName('description')[0]
print "Description: %s" % description.childNodes[0].data
Điều này sẽ tạo ra kết quả sau:
Root element : New Arrivals
*****Movie*****
Title: Enemy Behind
Type: War, Thriller
Format: DVD
Rating: PG
Description: Talk about a US-Japan war
*****Movie*****
Title: Transformers
Type: Anime, Science Fiction
Format: DVD
Rating: R
Description: A schientific fiction
*****Movie*****
Title: Trigun
Type: Anime, Action
Format: DVD
Rating: PG
Description: Vash the Stampede!
*****Movie*****
Title: Ishtar
Type: Comedy
Format: VHS
Rating: PG
Description: Viewable boredom
Để biết chi tiết đầy đủ về tài liệu API DOM, vui lòng tham khảo các API DOM Python tiêu chuẩn .