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)
- 第一个 stuname 元素
getElementsByTagName("stume")[0]
- stuname 元素的第一个子节点 (文本节点)
childNodes[0]
- 就是具体的文本数据了
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.遍历根节点可以获得子节点,然后就可以根据需求拿到需要的字段了。