Python中提供的XML解析方式:

方法

特点

SAX

SAX解析通过流模式在解析XML的过程中触发对应的事件(start_element、char_data、end_element)并调用用户定义的回调函数来处理XML文件。

DOM

将XML数据在内存中解析成一个树,通过对树的操作来操作XML,占用内存大,解析速度较慢,优点是可以任意遍历树的节点。

ElementTree

类似一个轻量级的DOM。




1. DOM 解析


DOM 解析器在解析 XML 文档时,一次性读取整个文档,把文档中所有元素保存在内存中的一个树结构中,之后可以利用 DOM 提供的各种函数来读取或修改文档内容和结构,也可以把修改过的内容写入 xml 文件。

from xml.dom.minidom import parse



python 中用 xml.dom.minidom 来解析 xml 文件。
示例xml:students.xml


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

<!DOCTYPE students [
        <!ELEMENT students (student)*>
        <!ELEMENT student (stuname|stuage|stusex)*>
        <!ATTLIST student
                id CDATA #REQUIRED>
        <!ELEMENT stuname (#PCDATA)>
        <!ELEMENT stuage (#PCDATA)>
        <!ELEMENT stusex (#PCDATA)>
        ]>
<students>
    <student id="1">
        <stuname>张三</stuname>
        <stuage>20</stuage>
        <stusex>女</stusex>
    </student>
    <student id="2">
        <stuname>李四</stuname>
        <stuage>21</stuage>
        <stusex>男</stusex>
    </student>
</students>

DOM 解析:


from xml.dom.minidom import parse
class Student:
    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'+self.age+'\t'+self.sex

l=[]
domTree=parse("students.xml")
root= domTree.documentElement
students=root.getElementsByTagName("student")
for s in students:
    name=s.getElementsByTagName('stuname')[0].childNodes[0].data
    age=s.getElementsByTagName('stuage')[0].childNodes[0].data
    sex = s.getElementsByTagName('stusex')[0].childNodes[0].data
    id=s.getAttribute('id')
    stu=Student(id,name,age,sex)
    l.append(stu)
for i in l:
    print(i)




2. SAX 解析


SAX 是一种基于事件驱动的 API,包括解析器和事件处理器。


解析器负责读取XML文档,并向事件处理器发送事件。而事件处理器则负责对事件作出响应,对传递的XML数据进行处理。
适用场景:
1、对大型文件进行处理;
2、只需要文件的部分内容,或者只需从文件中得到特定信息。
3、想建立自己的对象模型的时候。

sax 解析需要继承 ContentHandler 并重写其中的方法,ContentHandler 类中常用方法如下:
 
方法 参数 作用
startDocument(self) 文档启动时调用
endDocument(self) 解析器到达文档结尾时调用
startElement(self,name):元素名称,attrs:元素属性 遇到XML开始标签时调用
endElement(self,name):元素名称 遇到XML结束标签时调用
characters(self,content):文本内容 读取元素内容时调用
 
sax 模块常用方法
 
方法 作用
make_parser() 创建一个新的解析器对象并返回
parse() 创建一个 SAX 解析器并解析xml文档
parseString() 创建一个XML解析器并解析xml字符串
from xml.sax import parse

from xml.sax import ContentHandler

from xml.sax import parse, ContentHandler


class Student:
    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

stulist=[]


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


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

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

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

parse('students.xml',SaxParser())
for i in stulist:
    print(i)



3. ElementTree 解析


ElementTree 在 Python 中有两种实现 
一种是纯 Python 实现:xml.etree.ElementTree 
另一种是 C 语言实现:xml.etree.cElementTree 
建议使用 C 语言 实现的 ElementTree,因为它速度更快,占用内存更少 
在程序中导入模块时这样写(如果C语言实现的不能使用再使用纯Python实现的)
 
try:
 import xml.etree.cElementTree as ET
except ImportError:
 import xml.etree.ElementTree as ET


ElementTree 中 常用方法
 
方法                 作用
parse(xmlfile)     加载xml文件
fromstring(xmltext) 加载xml文件
findall()           获取指定的所有节点
find()             获取指定的节点
getchildren()     获取儿子节点
getiterator()     获取指定的所有节点,与findall()类似


属性 作用
attrib 获取节点的属性及属性值(以元祖的形式返回)
tag 获取节点名称
text 获取节点的文本值


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


class Student:
    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

stulist=[]
def test():
    tree=ET.parse('students.xml')
    students=tree.findall('student')
    for i in students:
        stu=Student()
        children=i.getchildren()
        stu.name= children[0].text
        stu.age= children[1].text
        stu.sex= children[2].text
        stu.id= i.attrib['id']
        stulist.append(stu)

test()
for j in stulist:
    print(j)