今日分享
Python解析XML文件
阅读本文大概约10分钟
XML 全称是Extensible Markup Language,意为可扩展标记语言,是一种用于标记电子文件使其具有结构性的标记语言。XML易于扩展,主要用来传输和存储数据,聚焦的是数据的内容。以XML结构存储数据的文件即为xml文件。
Python有三种方法解析XML:SAX、DOM、ElementTree。
测试用xml文件如下:其内容表示某仪器设备采集远程的数据包。
<?xml version="1.0" encoding="utf-8"?>
<data>
<meter id="1001" name="002008010217">
<id>1002001id>
<name>002008010217-1090name>
<sample_time>20191230075505sample_time>
<consumption>15878.59consumption>
meter>
<meter id="1002" name="002008010015">
<id>1003001id>
<name>002008010015-1090name>
<sample_time>20191230075507sample_time>
<consumption>33183.7consumption>
meter>
data>
在线代码格式化工具:https://tool.oschina.net/codeformat/xml
方法一:SAX(simple API for XML)
#SAX 是一种基于事件驱动的API,涉及两个部分:解析器(负责读取XML文件,并向事务处理器发送相应的事件)和事务处理器(对事件作出响应)。先创建一个新的XMLReader对象,然后设置XMLReader事件处理器ContentHandler,最后执行XMLReader的parse()方法。逐行扫描文档,一次处理一个标签,无须事先全部读取整个XML文档,对于大型文档的解析拥有巨大优势。
import xml.sax
class MeterHandler(xml.sax.ContentHandler):
def __init__(self):
self.id = ""
self.name = ""
self.sample_time = ""
self.consumption = ""
# 元素开始调用
def startElement(self, tag, attributes):
self.CurrentData = tag
if tag == "student":
met_id = meter.getAttribute('id')
met_name = meter.getAttribute('name')
print("met_id:", met_id,"met_name:", met_name)
# 元素结束调用
def endElement(self, tag):
if self.CurrentData == "id":
print(f"id:{self.id}")
elif self.CurrentData == "name":
print(f"name:{self.name}")
elif self.CurrentData == "sample_time":
print(f"sample_time:{self.sample_time}")
elif self.CurrentData == "consumption":
print(f"consumption:{self.consumption}")
else:
pass
self.CurrentData = ""
# 读取字符时调用
def characters(self, content):
if self.CurrentData == "id":
self.id = content
elif self.CurrentData == "name":
self.name = content
elif self.CurrentData == "sample_time":
self.sample_time = content
elif self.CurrentData == "consumption":
self.consumption = content
else:
pass
if (__name__ == "__main__"):
# 创建 XMLReader
parser = xml.sax.make_parser()
# 关闭命名空间
parser.setFeature(xml.sax.handler.feature_namespaces, 0)
# 重写 ContextHandler
Handler = MeterHandler()
parser.setContentHandler(Handler)
parser.parse(r".\test73\test1.xml")
方法二:DOM(Document Object Model)
#文档对象模型DOM是W3C组织推荐的处理可扩展标记语言标准编程接口,DOM解析器在解析XML文档时,一次性读取整个文档,数据在内存中解析成一个树结构里,通过DOM中函数读取或修改文档内容和结构。
from xml.dom.minidom import parse
import xml.dom.minidom
# 读取文件
domtree =xml.dom.minidom.parse(r'.\test73\test1.xml')
# 获取文档元素对象
data = domtree.documentElement
# 获取 meter
meters = data.getElementsByTagName('meter')
for meter in meters:
# 获取标签属性值
met_id = meter.getAttribute('id')
met_name = meter.getAttribute('name')
# 获取标签中内容
id = meter.getElementsByTagName('id')[0].childNodes[0].nodeValue
name = meter.getElementsByTagName('name')[0].childNodes[0].nodeValue
sample_time = meter.getElementsByTagName('sample_time')[0].childNodes[0].nodeValue
consumption = meter.getElementsByTagName('consumption')[0].childNodes[0].nodeValue
print('met_id:', met_id, ', met_name:',met_name)
print('id:', id, ', name:', name, ', sample_time:',sample_time,"consumption",consumption)
方法三:ElementTree
#ElementTree将XML数据在内存中解析成树,通过树来操作XML。代码相当简洁。
import xml.etree.ElementTree as ET
tree = ET.parse(r".\test73\test1.xml")
# 根节点
root = tree.getroot()
# 标签名
print('root_tag:',root.tag)
for met in root:
# 属性值
print ("met_id:",met.attrib["id"])
print ("met_name:",met.attrib["name"])
# 标签中内容
print ("id:", met[0].text)
print ("name:", met[1].text)
print("sample_time:", met[2].text)
print("consumption:", met[3].text)