python對XML的解析
常見的XML編程接口有DOM和SAX,這兩種接口處理XML文件的方式不同,當然使用場合也不同。
python有三種方法解析XML,SAX,DOM,以及ElementTree:
1.SAX (simple API for XML )
python使用SAX解析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結束標籤時調用。
Student.xml
<?xml version="1.0" encoding="utf-8" ?>
<Students shelf="金庸程序工程師">
<Student id="01">
<name>張三</name>
<age>29</age>
<sex>男</sex>
</Student>
<Student id="02">
<name>李四</name>
<age>20</age>
<sex>女</sex>
</Student>
<Student id="03">
<name>神鵰</name>
<age>299</age>
<sex>公</sex>
</Student>
</Students>
#sax解析
from xml.sax import ContentHandler
from xml.sax import parse
class Student:
def __init__(self,name=None,age=None,sex=None):
self.name=name
self.age=age
self.sex=sex
def __str__(self):
return self.name+','+str(self.age)+self.sex
students=[]
class saxdemo(ContentHandler):
def startDocument(self):
print("startDocument...")
pass
def endDocument(self):
print("endDocument...")
pass
def startElement(self, name, attrs):
print('startElement...')
if name=='Student':
self.student=Student()
def endElement(self, name):
print('endElement...')
if name=='name':
self.student.name=self.tag
if name=='age':
self.student.age=self.tag
if name=='sex':
self.student.sex=self.tag
if name=='Student':
students.append(self.student)
pass
def characters(self, content):
print('characters... content:%s'%(content))
self.tag=content
pass
parse('Student.xml',saxdemo())
for stu in students:
print(stu)
2.DOM(Document Object Model)
將XML數據在內存中解析成一個樹,通過對樹的操作來操作XML。
books.xml內容如下.
<?xml version="1.0" encoding="utf-8" ?>
<books shelf="金庸程序工程師">
<book id="01">
<bookname>python入門</bookname>
<author>李強</author>
<price>25</price>
</book>
<book id="02">
<bookname>java基礎</bookname>
<author>王洋</author>
<price>30</price>
</book>
<book id="03">
<bookname>神鵰俠侶</bookname>
<author>金庸</author>
<price>125</price>
</book>
</books>
#dom解析
from xml.dom.minidom import parse
import xml.dom.minidom
#使用minidom解析器打開xml文件
DOMTree=xml.dom.minidom.parse('book.xml')
books=DOMTree.documentElement
if books.hasAttribute("shelf"):
print("根節點 :%s"%(books.getAttribute("shelf")))
#獲取所有書籍節點
bookEs=books.getElementsByTagName("book")
#遍歷每本書籍,打印詳細信息
for book in bookEs:
if book.hasAttribute("id"):
print('book節點 id值爲%s'%(book.getAttribute("id")))
bookname=book.getElementsByTagName("bookname")[0]
print('book bookname:%s'%(bookname.childNodes[0].data))
author = book.getElementsByTagName("author")[0]
print('book author:%s' % (author.childNodes[0].data))
price = book.getElementsByTagName("price")[0]
print('book price:%s' % (price.childNodes[0].data))
3.ElementTree
對比其他 Python 處理 XML 的方案,xml.etree.ElementTree 模塊(下文我們以 ET 來表示)相對來說比較簡單,接口也較友好ElementTree提供的方法
find
(match) # 查找第一個匹配的子元素, match可以時tag或是xpaht路徑findall
(match) # 返回所有匹配的子元素列表findtext
(match, default=None) #iter
(tag=None) # 以當前元素爲根節點 創建樹迭代器,如果tag不爲None,則以tag進行過濾iterfind
(match)- parse(match) #從指定的 XML 文件構造一個
ElementTree
對象
#etree解析
import xml.etree.ElementTree as et
root=et.parse('Student.xml')
stus=root.findall("Student")
p=[]
for stu in stus:
student=Student()
student.name=stu.find("name").text
student.age=stu.find("age").text
student.sex=stu.find("sex").text
p.append(student)
for i in p:
print(i)