解析xml_Python解析XML文件

今日分享

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)

e879c823d382d83a5d54d3c169d5ae6a.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值