python之XML解析

Winter發表於2019-09-23

XML 指可擴充套件標記語言,標準通用標記語言的子集,是一種用於標記電子檔案使其具有結構性的標記語言。

XML 被設計用來傳輸和儲存資料。XML適用於跟蹤中小型資料而無需基於SQL的主幹。

Python 對 XML 的解析

常見的 XML 程式設計介面有 DOM 和 SAX,這兩種介面處理 XML 檔案的方式不同,使用場景也不同。

Python有三種方法解析XML,分別是SAX、DOM和ElementTree:

  • SAX:Python 標準庫包含 SAX 解析器,SAX 用事件驅動模型,通過在解析 XML 的過程中觸發一個個的事件並呼叫使用者定義的回撥函式來處理 XML 檔案。

  • DOM:將 XML 資料在記憶體中解析成一個樹,通過對樹的操作來操作 XML。

  • ElementTree:ElementTree(元素樹)就像一個輕量級的DOM,具有方便友好的API。程式碼可用性好,速度快,消耗記憶體少。

因DOM需要將XML資料對映到記憶體中的樹,會比較慢和消耗記憶體,而SAX流式讀取XML檔案,比較快,佔用記憶體少,但需要使用者實現回撥函式(handler)。

本章節使用到的 XML 例項檔案movies.xml內容如下:

<collection shelf="新品推薦">
<movie title="重返二十歲">
   <type>喜劇,親情,愛情,奇幻</type>
   <format>DVD</format>
   <year>2014</year>
   <rating>PG</rating>
   <stars>8</stars>
   <description>影片講述了一位七旬老太太不可思議變身為妙齡女子後,以新身份回到日常生活,引發的一系列啼笑皆非的奇幻故事</description>
</movie>
<movie title="流浪地球">
   <type>科幻、災難、冒險、動作</type>
   <format>DVD</format>
   <year>2019</year>
   <rating>R</rating>
   <stars>10</stars>
   <description>講述了太陽即將毀滅,已經不適合人類生存,而面對絕境,人類將開啟“流浪地球”計劃    </description>
</movie>
   <movie title="惡棍天使">
   <type>喜劇,愛情</type>
   <format>DVD</format>
   <year>2015</year>
   <rating>PG</rating>
   <stars>10</stars>
   <description>講述了高智商低情商女學霸查小刀遇到專職替人討債的惡棍莫非裡,倆人在神醫折耳根的介紹下互相“治療”發生的一系列故事</description>
</movie>
<movie title="戰狼">
   <type>動作,戰爭,軍事</type>
   <format>VHS</format>
   <year>2015</year>
   <rating>PG</rating>
   <stars>10</stars>
   <description>講述的是小人物成長為拯救國家和民族命運的孤膽英雄的傳奇故事</description>
</movie>
</collection>

使用SAX API解析XML

SAX 是一種基於事件驅動的API。利用 SAX 解析 XML 文件牽涉到兩個部分, 解析器事件處理器。解析器負責讀取 XML 文件,並向事件處理器傳送事件,如元素開始跟元素結束事件。而事件處理器則負責對事件作出響應,對傳遞的 XML 資料進行處理。

在 Python 中使用 sax 方式處理 xml 要先引入 xml.sax 中的 parse 函式,還有 xml.sax.handler 中的 ContentHandler。

ContentHandler 類方法介紹
  • characters(content)方法:
從行開始,遇到標籤之前,存在字元,content 的值為這些字串。
從一個標籤,遇到下一個標籤之前, 存在字元,content 的值為這些字串。
從一個標籤,遇到行結束符之前,存在字元,content 的值為這些字串。
標籤可以是開始標籤,也可以是結束標籤。
  • startDocument()方法:文件啟動的時候呼叫。

  • endDocument()方法:解析器到達文件結尾時呼叫。

  • startElement(name, attrs) 方法:遇到XML開始標籤時呼叫,name 是標籤的名字,attrs 是標籤的屬性值字典。

  • endElement(name) 方法:遇到XML結束標籤時呼叫。

make_parser方法

make_parser()方法用於建立一個新的解析器物件並返回。建立的解析器物件將是系統找到的第一個解析器型別。

語法如下:

xml.sax.make_parser(parser_list)
parser_list  -- 可選引數,解析器列表

parser方法

parser ()方法用於建立一個 SAX 解析器並解析xml文件。

語法如下:

xml.sax.parse( xmlfile, contenthandler[, errorhandler])
xmlfile -- xml檔名
contenthandler -- 必須是一個ContentHandler物件
errorhandler -- 如果指定該引數,errorhandler必須是一個SAX ErrorHandler物件

parseString方法

parseString()方法建立一個 XML 解析器並解析 xml 字串。

語法如下:

xml.sax.parseString(xmlstring, contenthandler[, errorhandler])
xmlstring -- xml字串
contenthandler -- 必須是一個ContentHandler的物件
errorhandler -- 如果指定該引數,errorhandler必須是一個SAX ErrorHandler物件

Python 解析XML例項

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 = ""
    # 元素開始呼叫
    def startElement(self, tag, attributes):
        self.CurrentData = tag
        if tag == "movie":
            print("-----電影資訊介紹-----")
            title = attributes["title"]
            print("Title:", title)
    # 元素結束呼叫
    def endElement(self, tag):
        if self.CurrentData == "type":
            print("型別:", self.type)
        elif self.CurrentData == "format":
            print("格式:", self.format)
        elif self.CurrentData == "year":
            print("時間:", self.year)
        elif self.CurrentData == "rating":
            print("評級:", self.rating)
        elif self.CurrentData == "stars":
            print("星星:", self.stars)
        elif self.CurrentData == "description":
            print("描述:", self.description, "\n")
        self.CurrentData = ""
    # 讀取字元時呼叫
    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__"):
    # 建立一個 XMLReader
    parser = xml.sax.make_parser()
    # 關閉名稱空間
    parser.setFeature(xml.sax.handler.feature_namespaces, 0)
    # 重寫 ContextHandler
    Handler = MovieHandler()
    parser.setContentHandler(Handler)
    parser.parse("movies.xml")

執行程式後輸出結果如下:

-----電影資訊介紹-----
Title: 重返二十歲
型別: 喜劇,親情,愛情,奇幻
格式: DVD
時間: 2014
評級: 7歲以上可以觀看
星星: 8
描述: 影片講述了一位七旬老太太不可思議變身為妙齡女子後,以新身份回到日常生活,引發的一系列啼笑皆非的奇幻故事 
-----電影資訊介紹-----
Title: 流浪地球
型別: 科幻、災難、冒險、動作
格式: DVD
時間: 2019
評級: R
星星: 10
描述: 講述了太陽即將毀滅,已經不適合人類生存,而面對絕境,人類將開啟“流浪地球”計劃     
-----電影資訊介紹-----
Title: 惡棍天使
型別: 喜劇,愛情
格式: DVD
時間: 2015
評級: PG
星星: 10
描述: 講述了高智商低情商女學霸查小刀遇到專職替人討債的惡棍莫非裡,倆人在神醫折耳根的介紹下互相“治療”發生的一系列故事 
-----電影資訊介紹-----
Title: 戰狼
型別: 動作,戰爭,軍事
格式: VHS
時間: 2015
評級: PG
星星: 10
描述: 講述的是小人物成長為拯救國家和民族命運的孤膽英雄的傳奇故事

使用DOM API解析XML

文件物件模型是來自W3C的跨語言API,用於訪問和修改XML文件。

DOM解析器在解析一個XML文件時,一次性讀取整個文件,把文件中所有元素儲存在記憶體中的一個樹結構裡。之後可以利用DOM 提供的不同的函式來讀取或修改文件的內容和結構,也可以把修改過的內容寫入xml檔案。

使用xml.dom.minidom來解析xml檔案時,minidom物件提供了一種簡單的解析器方法,可以從XML檔案中快速建立DOM樹。

示例:
from xml.dom.minidom import parse
import xml.dom.minidom
# 使用minidom解析器開啟XML文件
DOMTree = xml.dom.minidom.parse("movies.xml")
collection = DOMTree.documentElement
if collection.hasAttribute("shelf"):
   print ("根元素 : %s" % collection.getAttribute("shelf"))
# 在集合中獲取所有電影
movies = collection.getElementsByTagName("movie")
# 列印每部電影的詳細資訊
for movie in movies:
   print ("-----電影資訊介紹-----")
   if movie.hasAttribute("title"):
      print ("標題: %s" % movie.getAttribute("title"))
   type = movie.getElementsByTagName('type')[0]
   print ("型別: %s" % type.childNodes[0].data)
   format = movie.getElementsByTagName('format')[0]
   print ("格式: %s" % format.childNodes[0].data)
   rating = movie.getElementsByTagName('rating')[0]
   print ("等級: %s" % rating.childNodes[0].data)
   stars = movie.getElementsByTagName('stars')[0]
   print("星星: %s" % stars.childNodes[0].data)
   description = movie.getElementsByTagName('description')[0]
   print ("描述: %s" % description.childNodes[0].data, "\n")

執行程式後輸出結果如下:

根元素 : 新品推薦
-----電影資訊介紹-----
標題: 重返二十歲
型別: 喜劇,親情,愛情,奇幻
格式: DVD
等級: PG
星星: 8
描述: 影片講述了一位七旬老太太不可思議變身為妙齡女子後,以新身份回到日常生活,引發的一系列啼笑皆非的奇幻故事 
-----電影資訊介紹-----
標題: 流浪地球
型別: 科幻、災難、冒險、動作
格式: DVD
等級: R
星星: 10
描述: 講述了太陽即將毀滅,已經不適合人類生存,而面對絕境,人類將開啟“流浪地球”計劃     
-----電影資訊介紹-----
標題: 惡棍天使
型別: 喜劇,愛情
格式: DVD
等級: PG
星星: 10
描述: 講述了高智商低情商女學霸查小刀遇到專職替人討債的惡棍莫非裡,倆人在神醫折耳根的介紹下互相“治療”發生的一系列故事 
-----電影資訊介紹-----
標題: 戰狼
型別: 動作,戰爭,軍事
格式: VHS
等級: PG
星星: 10
描述: 講述的是小人物成長為拯救國家和民族命運的孤膽英雄的傳奇故事

參考: https://www.9xkd.com/

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69908432/viewspace-2657888/,如需轉載,請註明出處,否則將追究法律責任。

相關文章