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备份文件以及mysql数据库的脚本代码
Jun 10 Python
python之wxPython菜单使用详解
Sep 28 Python
Python中的条件判断语句基础学习教程
Feb 07 Python
彻彻底底地理解Python中的编码问题
Oct 15 Python
python将txt文件读取为字典的示例
Dec 22 Python
django项目中使用手机号登录的实例代码
Aug 15 Python
python实现按首字母分类查找功能
Oct 31 Python
Python 词典(Dict) 加载与保存示例
Dec 06 Python
完美解决TensorFlow和Keras大数据量内存溢出的问题
Jul 03 Python
python开发一个解析protobuf文件的简单编译器
Nov 17 Python
django学习之ajax post传参的2种格式实例
May 14 Python
如何解决.cuda()加载用时很长的问题
May 24 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
浅谈ThinkPHP中initialize和construct的区别
2017/04/01 PHP
JavaScript的public、private和privileged模式
2009/12/28 Javascript
6种javascript显示当前系统时间代码
2015/12/01 Javascript
jQuery实现图片走马灯效果的原理分析
2016/01/16 Javascript
jQuery解决$符号命名冲突
2016/06/18 Javascript
js只执行1次的函数示例
2016/07/20 Javascript
Javascript中关于Array.filter()的妙用详解
2016/12/04 Javascript
使用smartupload组件实现jsp+jdbc上传下载文件实例解析
2017/01/05 Javascript
原生javascript实现的全屏滚动功能示例
2017/09/19 Javascript
javascript中new Array()和var arr=[]用法区别
2017/12/01 Javascript
JavaScript实现的简单Tab点击切换功能示例
2018/07/06 Javascript
atom-design(Vue.js移动端组件库)手势组件使用教程
2019/05/16 Javascript
Vue使用Proxy监听所有接口状态的方法实现
2019/06/07 Javascript
Vue执行方法,方法获取data值,设置data值,方法传值操作
2020/08/05 Javascript
微信小程序实现弹幕墙(祝福墙)
2020/11/18 Javascript
js实现电灯开关效果
2021/01/19 Javascript
跟老齐学Python之从if开始语句的征程
2014/09/14 Python
Python数据结构与算法之完全树与最小堆实例
2017/12/13 Python
python selenium 弹出框处理的实现
2019/02/26 Python
Python操作excel的方法总结(xlrd、xlwt、openpyxl)
2019/09/02 Python
使用ITK-SNAP进行抠图操作并保存mask的实例
2020/07/01 Python
python GUI计算器的实现
2020/10/09 Python
如何在scrapy中集成selenium爬取网页的方法
2020/11/18 Python
台湾生鲜宅配:大口市集
2017/10/14 全球购物
Pam & Gela官网:美国性感前卫女装品牌
2018/07/19 全球购物
惠普香港官方商店:HP香港
2019/04/30 全球购物
英国拖鞋购买网站:Bedroom Athletics
2020/02/28 全球购物
mysql的最长数据库名,表名,字段名可以是多长
2014/04/21 面试题
中式婚礼主持词
2014/03/13 职场文书
年终奖发放方案
2014/06/02 职场文书
私人委托书格式
2014/09/10 职场文书
新学期开学寄语2016
2015/12/04 职场文书
关于社会实践的心得体会(2016最新版)
2016/01/25 职场文书
JavaScript 反射学习技巧
2021/10/16 Javascript
vue router 动态路由清除方式
2022/05/25 Vue.js
vue css 相对路径导入问题级踩坑记录
2022/06/05 Vue.js