天天看点

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.遍历根节点可以获得子节点,然后就可以根据需求拿到需要的字段了。

继续阅读