天天看點

XML和python的XML解析方法XML和XML解析

XML和XML解析

一、什麼是XML

XML 指可擴充标記語言(EXtensible Markup Language)

XML 是一種标記語言,很類似 HTML

XML 的設計宗旨是傳輸資料,而非顯示資料

XML 标簽沒有被預定義。您需要自行定義标簽。

XML 被設計為具有自我描述性。

XML 是 W3C 的推薦标準。

要注意的是,XML不做任何事情,它隻是用來存儲和傳輸資料的。

比如:

<?xml version="1.0" encoding="utf-8"?>
#DTD 的作用是定義在某個 XML 文檔中那些元素和屬性是合法的。
#DTD 被用來驗證 XML 資料。
<!DOCTYPE students [
    <!ELEMENT students (student+)>
    <!ELEMENT student (stuname,stuage,stusex)>
    <!ELEMENT stuname (#PCDATA)>
    <!ELEMENT stuage (#PCDATA)>
    <!ELEMENT stusex (#PCDATA)>
    <!ATTLIST student id CDATA #REQUIRED>
]>

<students>
    <student id="1">
        <stuname>張三</stuname>
        <stuage>21</stuage>
        <stusex>男</stusex>
    </student>
    <student id="2">
        <stuname>李靜</stuname>
        <stuage>20</stuage>
        <stusex>女</stusex>
    </student>
</students>
           

如上,就是一個XML格式的檔案。

我們可以看到,基本和HTML檔案格式差不多:

XML配置檔案固定格式:

1.标簽成對出現

2.區分大小寫

3.标簽要正确嵌套

4.開始部分

<?xml version="1.0" encoding="utf-8"?>

5.隻能有一個根節點

6.節點可以有屬性

二、XML解析

1.sax解析

python 标準庫包含SAX解析器,SAX用事件驅動模型,通過在解析XML的過程中觸發一個個的事件并調用使用者定義的回調函數來處理XML檔案。

SAX是一種基于事件驅動的API。

利用SAX解析XML文檔牽涉到兩個部分:解析器和事件處理器。

解析器負責讀取XML文檔,并向事件處理器發送事件,如元素開始跟元素結束事件;

而事件處理器則負責對事件作出相應,對傳遞的XML資料進行處理。

1、對大型檔案進行處理;

2、隻需要檔案的部分内容,或者隻需從檔案中得到特定資訊。

3、想建立自己的對象模型的時候。

在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結束标簽時調用。

代碼如下:

XML檔案同上,以下代碼是用SAX方法解析

from xml.sax import parse
from xml.sax.handler import ContentHandler

stulist=[]

class Stu:
    def __init__(self,id=None,name=None,age=None,sex=None):
        self.id=id
        self.name=name
        self.age=age
        self.sex=sex

    def __repr__(self):
        return self.id+"\t"+self.name+"\t\t"+self.age+"\t"+self.sex

class SaxParser(ContentHandler):
    def __init__(self,name=None):
        self.name=name
        self.stu=None

    def startDocument(self):
        print("startDocument")

    def endDocument(self):
        print("endDocument")

    def startElement(self, name, attrs):
        if name=="student":
            self.stu=Stu()
            self.stu.id=attrs['id']
        self.name=name

    def characters(self, content):
        if self.name=="stuname":
            self.stu.name=content
            #print(content)
        elif self.name=="stuage":
            self.stu.age=content
            #print(content)
        elif self.name=="stusex":
            self.stu.sex=content
            ##print(content)

    def endElement(self, name):
        if name=="student":
            stulist.append(self.stu)
        self.name=None

parse("XML.xml",SaxParser())

print(stulist)
           

以上代碼就是通過重寫ContentHandler類的方法來實作對XML檔案的解析。

2.DOM解析

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

from xml.dom.minidom import parse

stus=parse("XML.xml")

#擷取檔案根節點
root=stus.documentElement
print(root)
students=root.getElementsByTagName("student")
stulist=[]
for i in students:
    name=i.getElementsByTagName("stuname")[].childNodes[].data
    age = i.getElementsByTagName("stuage")[].childNodes[].data
    sex = i.getElementsByTagName("stusex")[].childNodes[].data
    id=i.getAttribute("id")
    print(name,age,sex,id)
    student={"學号":id,"姓名":name,"年齡":age,"性别":sex}
    stulist.append(student)

print(stulist)
           

getElementsByTagName("stume")[0]

- 第一個 stuname 元素

childNodes[0]

- stuname 元素的第一個子節點 (文本節點)

data

- 就是具體的文本資料了

常用的一些DOM屬性有:

x.nodeName - x 的名稱

x.nodeValue - x 的值

x.parentNode - x 的父節點

x.childNodes - x 的子節點

x.attributes - x 的屬性節點

注意:

x 是一個節點對象。

常用的一些DOM方法:

.getElementsByTagName(name) - 擷取帶有指定标簽名稱的所有元素

.getElementById(id) :傳回對擁有指定 id 的第一個對象的引用。

3.ElementTree

ElementTree生來就是為了處理XML,它在Python标準庫中有兩種實作:一種是純Python實作的,如xml.etree.ElementTree,另一種是速度快一點的xml.etree.cElementTree。注意:盡量使用C語言實作的那種,因為它速度更快,而且消耗的記憶體更少。

try:
    import xml.etree.cElementTree as ET
except ImportError:
    import xml.etree.ElementTree as ET

stulist=[]

class Stu:
    def __init__(self,id=None,name=None,age=None,sex=None):
        self.id=id
        self.name=name
        self.age=age
        self.sex=sex

    def __repr__(self):
        return self.id+"\t"+self.name+"\t\t"+self.age+"\t"+self.sex

def tset():
    tree=ET.parse("XML.xml")
    #root=tree.getroot()擷取根節點
    students=tree.findall("student")
    for stu in students:
        student=Stu()
        student.id=stu.attrib["id"]
        #獲根節點下的所有子節點
        children=stu.getchildren()
        student.name=children[].text
        student.age=children[].text
        student.sex=children[].text
        stulist.append(student)
tset()
print(stulist)
           

Elementtree解析XML檔案的過程就是:

1.導入ElementTree,import xml.etree.ElementTree as ET

2.解析Xml檔案找到根節點: 直接解析XML檔案并獲得根節點,

tree = ET.parse(‘XML檔案’)

root = tree.getroot()

3.周遊根節點可以獲得子節點,然後就可以根據需求拿到需要的字段了。

繼續閱讀