python中解析xml文件有三种常见的方法:一是xml.dom.*模块,她是W3C DOM API的实现;二是xml.sax.*模块,它是SAX API,这个模块牺牲了便捷性来换取速度和内存占用,SAX是一个基于事件的API,它可以“在空中”处理庞大数量的文档,不用完全加载进内存;三是xml.etree.ElementTree模块,它提供了轻量级的Python式API,相对于DOM来说,ET快了很多。
1、xml.etree.ElementTree
ElementTree生来就是为了处理XML,它在Python标准库中有两种实现:一种是纯Python实现的,如xml.etree.ElementTree,另一种是速度快一点的xml.etree.cElementTree。注意:尽量使用C语言实现的那种,因为它速度更快,而且消耗的内存更少。
2、xml.dom.*
文件对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展置标语言的标准编程接口。一个 DOM 的解析器在解析一个XML文档时,一次性读取整个文档,把文档中所有元素保存在内存中的一个树结构里,之后你可以利用DOM 提供的不同的函数来读取或修改文档的内容和结构,也可以把修改过的内容写入xml文件.
3、xml.sax.*
SAX是一种基于事件驱动的API,利用SAX解析XML牵涉到两个部分:解析器和事件处理器。其中解析器负责读取XML文档,并向事件处理器发送事件,如元素开始跟元素结束事件;而事件处理器则负责对事件作出相应,对传递的XML数据进行处理。python中使用sax方式处理xml要先引入xml.sax中的parse函数,还有xml.sax.handler中的ContentHandler。常使用在如下的情况下:一、对大型文件进行处理;二、只需要文件的部分内容,或者只需从文件中得到特定信息;三、想建立自己的对象模型的时候。
ContentHandler类方法介绍
(1)characters(content)方法
调用时机:从行开始,遇到标签之前,存在字符,content的值为这些字符串。从一个标签,遇到下一个标签之前, 存在字符,content的值为这些字符串。从一个标签,遇到行结束符之前,存在字符,content的值为这些字符串。标签可以是开始标签,也可以是结束标签。
(2)startDocument()方法 文档启动的时候调用。
(3)endDocument()方法 解析器到达文档结尾时调用。
(4)startElement(name, attrs)方法
遇到XML开始标签时调用,name是标签的名字,attrs是标签的属性值字典。
(5)endElement(name)方法 遇到XML结束标签时调用。
使用dom对三个节点内的内容进行修改并保存修改的内容:
import os
import os.path
import xml.dom.minidom
dirRoot = "存放原始xml文件的文件夹的名字"
dirRootNew = "存放修改后的xml文件的文件夹的名字"
for parent,dirnames,filenames in os.walk(dirRoot):
#eg:'000001.xml','000002.xml',........
print(filenames)
for filepath in filenames:
#eg:000001.xml
print(filepath)
xmlPath = os.path.join(parent,filepath)
#eg:F:/ObjectDetection/mstardata/test_AAA2/test_AAA2_xml/000001.xml
print(xmlPath)
xmlName = os.path.splitext(filepath)
#eg;000001
print(xmlName[0])
dom = xml.dom.minidom.parse(xmlPath)
root = dom.documentElement
folder = root.getElementsByTagName('folder')
file_name = root.getElementsByTagName('filename')
xmlPath = root.getElementsByTagName('path')
n0 = folder[0]
print(n0.firstChild.data)
p0 = file_name[0]
print(p0.firstChild.data)
x0 = xmlPath[0]
print(x0.firstChild.data)
stringName = xmlName[0] + '.jpg'
print(stringName)
stringPath = 'F:/ObjectDetection/mstardata/test_AAA2/test_AAA2_ps/'+stringName
n0.firstChild.data = 'VOC2007'
p0.firstChild.data = stringName
x0.firstChild.data = stringPath
print(n0.firstChild.data)
print(p0.firstChild.data)
print(x0.firstChild.data)
#保存修改到xml文件中
with open(os.path.join(dirRootNew,filepath),'w') as fh:
dom.writexml(fh)
print('写入name/pose OK!')