Python-解析 XML


  • 簡介

    XML 全稱 Extensible Markup Language,中文譯為可擴展標記語言。

  • XML 之前有兩個先行者:SGML 和 HTML,率先登場的是 SGML, 盡管它功能強大,但文檔結構復雜,既不容易學也不易於使用,因此幾個主要的瀏覽器廠商均拒絕支持 SGML,這些因素限制了 SGML 在網上的傳播性;1989 年 HTML 登場,它繼承了 SGML 諸多優點,去除了 SGML 復雜龐大的缺點,HTML 在數據顯示上表現十分出色,但它的語法是不可擴展的,因此其無法描述數據、可讀性差,沒辦法人們再次將目光轉向 SGML,經過對 SGML 一系列改造,終於在 1998 年,XML 第一個版本問世。

  • 簡單來說就是:XML 和 HTML 均由 SGML 改造而來,HTML 是一種頁面技術,聚焦的是數據的顯示,而 XML 易於擴展,主要用來傳送和存儲數據,聚焦的是數據的內容。
  • 解析

    解析方式

    Python 有三種 XML 解析方式:SAX(simple API for XML)、DOM(Document Object Model)、ElementTree。

    • DOM 方式:DOM 中文譯為文檔對象模型,是 W3C 組織推薦的標准編程接口,它將 XML 數據在內存中解析成一個樹,通過對樹的操作來操作 XML。

    • SAX 方式:SAX 是一個用於處理 XML 事件驅動的模型,它逐行掃描文檔,一邊掃描一邊解析,對於大型文檔的解析擁有巨大優勢,盡管不是 W3C 標准,但它卻得到了廣泛認可。

    • ElementTree 方式:ElementTree 相對於 DOM 來說擁有更好的性能,與 SAX 性能差不多,API 使用也很方便。

    具體實現

    在具體解析之前我們先准備一個 XML,如下所示:

  • test.xml
  • <?xml version="1.0" encoding="utf-8"?>
    <list>
    <student id="stu1" name="stu">
       <id>1001</id>
       <name>張三</name>
       <age>22</age>
       <gender>男</gender>
    </student>
    <student id="stu2" name="stu">
       <id>1002</id>
       <name>李四</name>
       <age>21</age>
       <gender>女</gender>
    </student>
    </list>

     

  • DOM 方式解析

    使用 DOM 方式,首先要對其 API 有一定了解,如果不了解,網上的教程也比較多,比如:DOM 教程,下面看一下使用示例。

  • from xml.dom.minidom import parse
    
    # 讀取文件
    dom = parse('test.xml')
    # 獲取文檔元素對象
    data = dom.documentElement
    # 獲取 student
    stus = data.getElementsByTagName('student')
    for stu in stus:
        # 獲取標簽屬性值
        st_id = stu.getAttribute('id')
        st_name = stu.getAttribute('name')
        # 獲取標簽中內容
        id = stu.getElementsByTagName('id')[0].childNodes[0].nodeValue
        name = stu.getElementsByTagName('name')[0].childNodes[0].nodeValue
        age = stu.getElementsByTagName('age')[0].childNodes[0].nodeValue
        gender = stu.getElementsByTagName('gender')[0].childNodes[0].nodeValue
        print('st_id:', st_id,  ', st_name:',st_name)
        print('id:', id, ', name:', name, ', age:', age, ', gender:',gender)

     

  • 輸出結果:
  • st_id: stu1 , st_name: stu
    id: 1001 , name: 張三 , age: 22 , gender: 男
    st_id: stu2 , st_name: stu
    id: 1002 , name: 李四 , age: 21 , gender: 女

     

  • 通過輸出結果,我們可以發現已經獲取了標簽屬性值和標簽內容了。
  • SAX 方式解析

    使用 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 結束標簽時調用。

    下面通過示例看一下如何通過 SAX 方式解析 XML。

  • import xml.sax
    
    class StudentHandler(xml.sax.ContentHandler):
        def __init__(self):
            self.id = ""
            self.name = ""
            self.age = ""
            self.gender = ""
    
        # 元素開始調用
        def startElement(self, tag, attributes):
            self.CurrentData = tag
            if tag == "student":
                stu_name = attributes["name"]
                print("stu_name:", stu_name)
    
        # 元素結束調用
        def endElement(self, tag):
            if self.CurrentData == "id":
                print("id:", self.id)
            elif self.CurrentData == "name":
                print("name:", self.name)
            elif self.CurrentData == "age":
                print("age:", self.age)
            elif self.CurrentData == "gender":
                print("gender:", self.gender)
            self.CurrentData = ""
    
        # 讀取字符時調用
        def characters(self, content):
            if self.CurrentData == "id":
                self.id = content
            elif self.CurrentData == "name":
                self.name = content
            elif self.CurrentData == "age":
                self.age = content
            elif self.CurrentData == "gender":
                self.gender = content
    
    if (__name__ == "__main__"):
        # 創建 XMLReader
        parser = xml.sax.make_parser()
        # 關閉命名空間
        parser.setFeature(xml.sax.handler.feature_namespaces, 0)
        # 重寫 ContextHandler
        Handler = StudentHandler()
        parser.setContentHandler(Handler)
        parser.parse("test.xml")

     

  • 輸出結果:
  • stu_name: stu
    id: 1001
    name: 張三
    age: 22
    gender: 男
    stu_name: stu
    id: 1002
    name: 李四
    age: 21
    gender: 女

     

  • ElementTree 方式解析

    Python 提供了兩種 ElementTree 的實現方式。一個是純 Python 實現的 xml.etree.ElementTree,另一個是 C 語言實現 xml.etree.cElementTree,使用 C 語言實現的方式速度更快且內存消耗更少。Python3.3 之后,ElemenTree 模塊會自動優先使用 C 加速器,如果不存在 C 實現,則會使用 Python 實現。因此,使用 Python3.3+ 時,只需要 import xml.etree.ElementTree 即可。下面看一下示例。

  • import xml.etree.ElementTree as ET
    
    tree = ET.parse("test.xml")
    # 根節點
    root = tree.getroot()
    # 標簽名
    print('root_tag:',root.tag)
    for stu in root:
        # 屬性值
        print ("stu_name:", stu.attrib["name"])
        # 標簽中內容
        print ("id:", stu[0].text)
        print ("name:", stu[1].text)
        print("age:", stu[2].text)
        print("gender:", stu[3].text)

     

  • 輸出結果:
  • root_tag: list
    stu_name: stu
    id: 1001
    name: 張三
    age: 22
    gender: 男
    stu_name: stu
    id: 1002
    name: 李四
    age: 21
    gender: 女

     


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM