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 相关文章推荐
打开电脑上的QQ的python代码
Feb 10 Python
Python使用MYSQLDB实现从数据库中导出XML文件的方法
May 11 Python
python下paramiko模块实现ssh连接登录Linux服务器
Jun 03 Python
python 系统调用的实例详解
Jul 11 Python
Python3 加密(hashlib和hmac)模块的实现
Nov 23 Python
Python2.7下安装Scrapy框架步骤教程
Dec 22 Python
Python基于多线程操作数据库相关问题分析
Jul 11 Python
Pandas中Series和DataFrame的索引实现
Jun 27 Python
python SQLAlchemy的Mapping与Declarative详解
Jul 04 Python
学python最电脑配置有要求么
Jul 05 Python
Python3合并两个有序数组代码实例
Aug 11 Python
教你如何用python操作摄像头以及对视频流的处理
Oct 12 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用数组返回无限分类的列表数据的代码
2010/08/08 PHP
PHP设计模式之迭代器模式的深入解析
2013/06/13 PHP
php实现用于删除整个目录的递归函数
2015/03/16 PHP
PHP微信红包API接口
2015/12/05 PHP
PHP实现自动识别原编码并对字符串进行编码转换的方法
2016/07/13 PHP
Laravel框架实现的rbac权限管理操作示例
2019/01/16 PHP
Jquery 基础学习笔记之文档处理
2009/05/29 Javascript
jQuery EasyUI API 中文文档 - DataGrid数据表格
2011/11/17 Javascript
js 左右悬浮对联广告代码示例
2014/12/12 Javascript
javascript去除字符串左右两端的空格
2015/02/05 Javascript
Javascript中For In语句用法实例
2015/05/14 Javascript
原生Javascript插件开发实践
2017/01/09 Javascript
Node.js  REPL (交互式解释器)实例详解
2017/08/06 Javascript
React进阶学习之组件的解耦之道
2017/08/07 Javascript
JS设计模式之数据访问对象模式的实例讲解
2017/09/30 Javascript
浅谈Vue Element中Select下拉框选取值的问题
2018/03/01 Javascript
vue表单自定义校验规则介绍
2018/08/28 Javascript
从Vuex中取出数组赋值给新的数组,新数组push时报错的解决方法
2018/09/18 Javascript
vue elementUI table表格数据 滚动懒加载的实现方法
2019/04/04 Javascript
JavaScript单线程和任务队列原理解析
2020/02/04 Javascript
jquery实现点击弹出对话框
2020/02/08 jQuery
vue循环中点击选中再点击取消(单选)的实现
2020/09/10 Javascript
python daemon守护进程实现
2016/08/27 Python
python django model联合主键的例子
2019/08/06 Python
Django实现文件上传和下载功能
2019/10/06 Python
Python使用Pandas库常见操作详解
2020/01/16 Python
C#实现启动一个进程
2016/10/01 面试题
教师个人自我鉴定
2014/02/08 职场文书
二手房购房意向书范本
2014/04/01 职场文书
小区物业门卫岗位职责
2014/04/10 职场文书
班组拓展活动方案
2014/08/14 职场文书
2015年双拥工作总结
2015/04/08 职场文书
学习《中小学教师职业道德规范》心得体会
2016/01/18 职场文书
2019年消防宣传标语集锦
2019/11/21 职场文书
HTML+CSS+JS实现图片的瀑布流布局的示例代码
2021/04/22 HTML / CSS
JAVA API 实用类 String详解
2021/10/05 Java/Android