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 相关文章推荐
在Python的Django框架中编写错误提示页面
Jul 22 Python
Python读取指定目录下指定后缀文件并保存为docx
Apr 23 Python
python opencv 直方图反向投影的方法
Feb 24 Python
matplotlib 输出保存指定尺寸的图片方法
May 24 Python
python实现诗歌游戏(类继承)
Feb 26 Python
python3 线性回归验证方法
Jul 09 Python
弄懂这56个Python使用技巧(轻松掌握Python高效开发)
Sep 18 Python
在python中实现求输出1-3+5-7+9-......101的和
Apr 02 Python
通过Python实现Payload分离免杀过程详解
Jul 13 Python
python/golang 删除链表中的元素
Sep 14 Python
PyCharm安装PyQt5及其工具(Qt Designer、PyUIC、PyRcc)的步骤详解
Nov 02 Python
简单谈谈Python面向对象的相关知识
Jun 28 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
PHP逐行输出(ob_flush与flush的组合)
2012/02/04 PHP
php实例分享之mysql数据备份
2014/05/19 PHP
个人写的PHP验证码生成类分享
2014/08/21 PHP
php查看网页源代码的方法
2015/03/13 PHP
php判断一个数组是否为有序的方法
2015/03/27 PHP
php自定义排序uasort函数示例【二维数组按指定键值排序】
2019/06/19 PHP
Laravel实现搜索的时候分页并携带参数
2019/10/15 PHP
laravel5.6 框架操作数据 Eloquent ORM用法示例
2020/01/26 PHP
jQuery的attr与prop使用介绍
2013/10/10 Javascript
原生javascript实现简单的datagrid数据表格
2015/01/02 Javascript
Javascript设计模式之观察者模式的多个实现版本实例
2015/03/03 Javascript
js实现模拟计算器退格键删除文字效果的方法
2015/05/07 Javascript
浅谈JavaScript异常处理语句
2015/06/26 Javascript
js采用concat和sort将N个数组拼接起来的方法
2016/01/21 Javascript
改变checkbox默认选中状态及取值的实现代码
2016/05/26 Javascript
NodeJS基础API搭建服务器详细过程记录
2017/04/01 NodeJs
利用vueJs实现图片轮播实例代码
2017/06/03 Javascript
bootstrap精简教程_动力节点Java学院整理
2017/07/14 Javascript
jQuery实现的点击按钮改变样式功能示例
2018/07/21 jQuery
vue代码分割的实现(codesplit)
2018/11/13 Javascript
Vue scrollBehavior 滚动行为实现后退页面显示在上次浏览的位置
2019/05/27 Javascript
vue项目中监听手机物理返回键的实现
2020/01/18 Javascript
详解Python中的from..import绝对导入语句
2016/06/21 Python
你应该知道的python列表去重方法
2017/01/17 Python
Python使用type关键字创建类步骤详解
2019/07/23 Python
Python基于read(size)方法读取超大文件
2020/03/12 Python
Python如何在windows环境安装pip及rarfile
2020/06/15 Python
PyCharm中配置PySide2的图文教程
2020/06/18 Python
解决python 虚拟环境删除包无法加载的问题
2020/07/13 Python
购买一个高级域名:BuyDomains
2018/03/11 全球购物
会计自我鉴定范文
2013/10/06 职场文书
前台文员岗位职责及工作流程
2013/11/19 职场文书
写演讲稿所需要注意的4个条件
2014/01/09 职场文书
社区党的群众路线教育实践活动领导班子对照检查材料
2014/09/25 职场文书
2014年个人师德工作总结
2014/12/04 职场文书
厉行节约工作总结
2015/08/12 职场文书