Python实现XML文件解析的示例代码


Posted in Python onFebruary 05, 2018

1. XML简介

XML(eXtensible Markup Language)指可扩展标记语言,被设计用来传输和存储数据,已经日趋成为当前许多新生技术的核心,在不同的领域都有着不同的应用。它是web发展到一定阶段的必然产物,既具有SGML的核心特征,又有着HTML的简单特性,还具有明确和结构良好等许多新的特性。

test.XML文件

<?xml version="1.0" encoding="utf-8"?>
<catalog>
  <maxid>4</maxid>
  <login username="pytest" passwd='123456'>
    <caption>Python</caption>
    <item id="4">
      <caption>测试</caption>
    </item>
  </login>
  <item id="2">
    <caption>Zope</caption>
  </item>
</catalog>

XML详细介绍可以参考: http://www.w3school.com.cn/xmldom/dom_nodetype.asp

2. XML文件解析

python解析XML常见的有三种方法:一是xml.dom.*模块,它是W3C DOM API的实现,若需要处理DOM API则该模块很适合;二是xml.sax.*模块,它是SAX API的实现,这个模块牺牲了便捷性来换取速度和内存占用,SAX是一个基于事件的API,这就意味着它可以“在空中”处理庞大数量的的文档,不用完全加载进内存;三是xml.etree.ElementTree模块(简称 ET),它提供了轻量级的Python式的API,相对于DOM来说ET 快了很多,而且有很多令人愉悦的API可以使用,相对于SAX来说ET的ET.iterparse也提供了 “在空中” 的处理方式,没有必要加载整个文档到内存,ET的性能的平均值和SAX差不多,但是API的效率更高一点而且使用起来很方便。

2.1 xml.dom.*

文件对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展置标语言的标准编程接口。一个 DOM 的解析器在解析一个XML文档时,一次性读取整个文档,把文档中所有元素保存在内存中的一个树结构里,之后你可以利用DOM 提供的不同的函数来读取或修改文档的内容和结构,也可以把修改过的内容写入xml文件。python中用xml.dom.minidom来解析xml文件。

a. 获得子标签

b. 区分相同标签名的标签

c. 获取标签属性值

d. 获取标签对之间的数据

#coding=utf-8

#通过minidom解析xml文件
import xml.dom.minidom as xmldom
import os
''' 
XML文件读取 
<?xml version="1.0" encoding="utf-8"?>
<catalog>
  <maxid>4</maxid>
  <login username="pytest" passwd='123456'>dasdas
    <caption>Python</caption>
    <item id="4">
      <caption>测试</caption>
    </item>
  </login>
  <item id="2">
    <caption>Zope</caption>
  </item>
</catalog>

'''

xmlfilepath = os.path.abspath("test.xml")
print ("xml文件路径:", xmlfilepath)

# 得到文档对象
domobj = xmldom.parse(xmlfilepath)
print("xmldom.parse:", type(domobj))
# 得到元素对象
elementobj = domobj.documentElement
print ("domobj.documentElement:", type(elementobj))

#获得子标签
subElementObj = elementobj.getElementsByTagName("login")
print ("getElementsByTagName:", type(subElementObj))

print (len(subElementObj))
# 获得标签属性值
print (subElementObj[0].getAttribute("username"))
print (subElementObj[0].getAttribute("passwd"))

#区分相同标签名的标签
subElementObj1 = elementobj.getElementsByTagName("caption")
for i in range(len(subElementObj1)):
  print ("subElementObj1[i]:", type(subElementObj1[i]))
  print (subElementObj1[i].firstChild.data) #显示标签对之间的数据

输出结果:

>>> D:\Pystu>python xml_instance.py
>>> xml文件路径: D:\Pystu\test.xml
>>> xmldom.parse: <class 'xml.dom.minidom.Document'>
>>> domobj.documentElement: <class 'xml.dom.minidom.Element'>
>>> getElementsByTagName: <class 'xml.dom.minicompat.NodeList'>
>>> username: pytest
>>> passwd: 123456
>>> subElementObj1[i]: <class 'xml.dom.minidom.Element'>
>>> Python
>>> subElementObj1[i]: <class 'xml.dom.minidom.Element'>
>>> 测试
>>> subElementObj1[i]: <class 'xml.dom.minidom.Element'>
>>> Zope

2.2 xml.etree.ElementTree

ElementTree生来就是为了处理XML,它在Python标准库中有两种实现:一种是纯Python实现的,如xml.etree.ElementTree,另一种是速度快一点的xml.etree.cElementTree。注意:尽量使用C语言实现的那种,因为它速度更快,而且消耗的内存更少。

a. 遍历根节点的下一层

b. 下标访问各个标签、属性、文本

c. 查找root下的指定标签

d. 遍历XML文件

e. 修改XML文件

#coding=utf-8

#通过解析xml文件
'''
try:
  import xml.etree.CElementTree as ET
except:
  import xml.etree.ElementTree as ET

从Python3.3开始ElementTree模块会自动寻找可用的C库来加快速度  
'''
import xml.etree.ElementTree as ET
import os
import sys
''' 
XML文件读取 
<?xml version="1.0" encoding="utf-8"?>
<catalog>
  <maxid>4</maxid>
  <login username="pytest" passwd='123456'>dasdas
    <caption>Python</caption>
    <item id="4">
      <caption>测试</caption>
    </item>
  </login>
  <item id="2">
    <caption>Zope</caption>
  </item>
</catalog>
'''

#遍历xml文件
def traverseXml(element):
  #print (len(element))
  if len(element)>0:
    for child in element:
      print (child.tag, "----", child.attrib)
      traverseXml(child)
  #else:
    #print (element.tag, "----", element.attrib)
    

if __name__ == "__main__":
  xmlFilePath = os.path.abspath("test.xml")
  print(xmlFilePath)
  try:
    tree = ET.parse(xmlFilePath)
    print ("tree type:", type(tree))
  
    # 获得根节点
    root = tree.getroot()
  except Exception as e: #捕获除与程序退出sys.exit()相关之外的所有异常
    print ("parse test.xml fail!")
    sys.exit()
  print ("root type:", type(root))  
  print (root.tag, "----", root.attrib)
  
  #遍历root的下一层
  for child in root:
    print ("遍历root的下一层", child.tag, "----", child.attrib)

  #使用下标访问
  print (root[0].text)
  print (root[1][1][0].text)

  print (20 * "*")
  #遍历xml文件
  traverseXml(root)
  print (20 * "*")

  #根据标签名查找root下的所有标签
  captionList = root.findall("item") #在当前指定目录下遍历
  print (len(captionList))
  for caption in captionList:
    print (caption.tag, "----", caption.attrib, "----", caption.text)

  #修改xml文件,将passwd修改为999999
  login = root.find("login")
  passwdValue = login.get("passwd")
  print ("not modify passwd:", passwdValue)
  login.set("passwd", "999999")  #修改,若修改text则表示为login.text
  print ("modify passwd:", login.get("passwd"))

输出结果:

>>> D:\Pystu\test.xml
>>> tree type: <class 'xml.etree.ElementTree.ElementTree'>
>>> root type: <class 'xml.etree.ElementTree.Element'>
>>> catalog ---- {}
>>> 遍历root的下一层 maxid ---- {}
>>> 遍历root的下一层 login ---- {'username': 'pytest', 'passwd': '123456'}
>>> 遍历root的下一层 item ---- {'id': '2'}
>>> 4
>>> 测试
>>> ********************
>>> maxid ---- {}
>>> login ---- {'username': 'pytest', 'passwd': '123456'}
>>> caption ---- {}
>>> item ---- {'id': '4'}
>>> caption ---- {}
>>> item ---- {'id': '2'}
>>> caption ---- {}
>>> ********************
>>> 1
>>> item ---- {'id': '2'} ----
>>> not modify passwd: 123456
>>> modify passwd: 999999

附:

#coding=utf-8

'''
  XML解析类
  @功能-结点的增删改查
'''
import xml.etree.ElementTree as ET
import sys
import os.path

class XmlParse:
  def __init__(self, file_path):
    self.tree = None
    self.root = None
    self.xml_file_path = file_path

  def ReadXml(self):
    try:
      print("xmlfile:", self.xml_file_path)
      self.tree = ET.parse(self.xml_file_path)
      self.root = self.tree.getroot()
    except Exception as e:
      print ("parse xml faild!")
      sys.exit()
    else:
      print ("parse xml success!")      
    finally: 
      return self.tree
        
  def CreateNode(self, tag, attrib, text):
    element = ET.Element(tag, attrib)
    element.text = text
    print ("tag:%s;attrib:%s;text:%s" %(tag, attrib, text))
    return element
       
  def AddNode(self, Parent, tag, attrib, text):
    element = self.CreateNode(tag, attrib, text)
    if Parent:
      Parent.append(element)
      el = self.root.find("lizhi")
      print (el.tag, "----", el.attrib, "----", el.text)
    else:
      print ("parent is none")

  def WriteXml(self, destfile):
    dest_xml_file = os.path.abspath(destfile)
    self.tree.write(dest_xml_file, encoding="utf-8",xml_declaration=True)
    

if __name__ == "__main__":
  xml_file = os.path.abspath("test.xml")
  parse = XmlParse(xml_file)
  tree = parse.ReadXml()
  root = tree.getroot()
  print (root)
  parse.AddNode(root, "Python", {"age":"22", "hello":"world"}, "YES")
  
  parse.WriteXml("testtest.xml")

2.3 xml.sax.*

SAX是一种基于事件驱动的API,利用SAX解析XML牵涉到两个部分:解析器和事件处理器。

解析器负责读取XML文档,并向事件处理器发送事件,如元素开始跟元素结束事件

事件处理器则负责对事件作出相应,对传递的XML数据进行处理

常用场景:

(1)对大型文件进行处理

(2)只需文件的部分内容,或只需从文件中得到特定信息

(3)想建立自己的对象模型

基于事件驱动的SAX解析XML内容的知识后续补充!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
一个基于flask的web应用诞生 flask和mysql相连(4)
Apr 11 Python
Python微信库:itchat的用法详解
Aug 14 Python
Python在信息学竞赛中的运用及Python的基本用法(详解)
Aug 15 Python
Python使用matplotlib绘制余弦的散点图示例
Mar 14 Python
Python实现读取SQLServer数据并插入到MongoDB数据库的方法示例
Jun 09 Python
python实现人民币大写转换
Jun 20 Python
记录Python脚本的运行日志的方法
Jun 05 Python
在python中画正态分布图像的实例
Jul 08 Python
python实现按行分割文件
Jul 22 Python
python烟花效果的代码实例
Feb 25 Python
python爬虫爬取图片的简单代码
Jan 18 Python
Python中的 enumerate和zip详情
May 30 Python
Python下载网络文本数据到本地内存的四种实现方法示例
Feb 05 #Python
Python实现屏幕截图的两种方式
Feb 05 #Python
Python实现连接两个无规则列表后删除重复元素并升序排序的方法
Feb 05 #Python
用python实现对比两张图片的不同
Feb 05 #Python
使用pygame模块编写贪吃蛇的实例讲解
Feb 05 #Python
Python安装模块的常见问题及解决方法
Feb 05 #Python
Python实现的用户登录系统功能示例
Feb 05 #Python
You might like
dede全站URL静态化改造[070414更正]
2007/04/17 PHP
Ping服务的php实现方法,让网站快速被收录
2012/02/04 PHP
PHP新手用的Insert和Update语句构造类
2012/03/31 PHP
PHP转换IP地址到真实地址的方法详解
2013/06/09 PHP
推荐十款免费 WordPress 插件
2015/03/24 PHP
开启PHP的伪静态模式
2015/12/31 PHP
javascript数组使用调用方法汇总
2007/12/08 Javascript
兼容IE、FireFox、Chrome等浏览器的xml处理函数js代码
2011/11/30 Javascript
javascript (用setTimeout而非setInterval)
2011/12/28 Javascript
JQuery 中几个类选择器的简单使用介绍
2013/03/14 Javascript
jQuery Trim去除字符串首尾空字符的实现方法说明
2014/02/11 Javascript
简单的js图片轮换代码(js图片轮播)
2014/05/06 Javascript
14款经典网页图片和文字特效的jQuery插件-前端开发必备
2015/08/25 Javascript
Prototype框架详解
2015/11/25 Javascript
JavaScript保留关键字汇总
2015/12/01 Javascript
简单实现js倒计时功能
2017/02/13 Javascript
Angular开发者指南之入门介绍
2017/03/05 Javascript
Node 升级到最新稳定版的方法分享
2018/05/17 Javascript
react 父子组件之间通讯props
2018/09/08 Javascript
详解JS浏览器事件循环机制
2019/03/27 Javascript
使用Vue父子组件通信实现todolist的功能示例代码
2019/04/11 Javascript
vue权限问题的完美解决方案
2019/05/08 Javascript
小程序如何获取多个formId实现详解
2019/09/20 Javascript
将RGB值转换为灰度值的简单算法
2019/10/09 Javascript
Vue项目中使用jsonp抓取跨域数据的方法
2019/11/10 Javascript
js中的面向对象之对象常见创建方法详解
2019/12/16 Javascript
Jquery如何使用animation动画效果改变背景色的代码
2020/07/20 jQuery
Vue 解决父组件跳转子路由后当前导航active样式消失问题
2020/07/21 Javascript
[01:46]辉夜杯—打造中国DOTA新格局
2015/12/25 DOTA
[01:03:18]DOTA2-DPC中国联赛 正赛 RNG vs Dynasty BO3 第一场 1月29日
2021/03/11 DOTA
婴儿鞋,独特的婴儿服装和配件:Zutano
2018/11/03 全球购物
企业管理培训感言
2014/01/27 职场文书
村创先争优活动总结
2014/08/28 职场文书
会议欢迎词范文
2015/01/27 职场文书
2016年教师寒假学习心得体会
2015/10/09 职场文书
公司趣味运动会开幕词
2016/03/04 职场文书