python解析xml文件方式(解析、更新、写入)


Posted in Python onMarch 05, 2020

Overview

这篇博客内容将包括对XML文件的解析、追加新元素后写入到XML,以及更新原XML文件中某结点的值。使用的是python的xml.dom.minidom包,详情可见其官方文档:xml.dom.minidom官方文档。全文都将围绕以下的customer.xml进行操作:

<?xml version="1.0" encoding="utf-8" ?>
<!-- This is list of customers -->
<customers>
 <customer ID="C001">
  <name>Acme Inc.</name>
  <phone>12345</phone>
  <comments>
   <![CDATA[Regular customer since 1995]]>
  </comments>
 </customer>
 <customer ID="C002">
  <name>Star Wars Inc.</name>
  <phone>23456</phone>
  <comments>
   <![CDATA[A small but healthy company.]]>
  </comments>
 </customer>
</customers>

CDATA:在XML中,不会被解析器解析的部分数据。

声明:在本文中,结点和节点被视为了同一个概念,你可以在全文的任何地方替换它,我个人感觉区别不是很大,当然,你也可以看做是我的打字输入错误。

1. 解析XML文件

在解析XML时,所有的文本都是储存在文本节点中的,且该文本节点被视为元素结点的子结点,例如:2005,元素节点 ,拥有一个值为 “2005” 的文本节点,“2005” 不是 元素的值,最常用的方法就是getElementsByTagName()方法了,获取到结点后再进一步根据文档结构解析即可。

具体的理论就不过多描述,配合上述XML文件和下面的代码,你将清楚的看到操作方法,下面的代码执行的工作是将所有的结点名称以及结点信息输出一下:

# -*- coding: utf-8 -*-
"""
  @Author : LiuZhian
  @Time  : 2019/4/24 0024 上午 9:19
  @Comment : 
"""
from xml.dom.minidom import parse
def readXML():
 domTree = parse("./customer.xml")
 # 文档根元素
 rootNode = domTree.documentElement
 print(rootNode.nodeName)

 # 所有顾客
 customers = rootNode.getElementsByTagName("customer")
 print("****所有顾客信息****")
 for customer in customers:
 if customer.hasAttribute("ID"):
  print("ID:", customer.getAttribute("ID"))
  # name 元素
  name = customer.getElementsByTagName("name")[0]
  print(name.nodeName, ":", name.childNodes[0].data)
  # phone 元素
  phone = customer.getElementsByTagName("phone")[0]
  print(phone.nodeName, ":", phone.childNodes[0].data)
  # comments 元素
  comments = customer.getElementsByTagName("comments")[0]
  print(comments.nodeName, ":", comments.childNodes[0].data)

if __name__ == '__main__':
 readXML()

python解析xml文件方式(解析、更新、写入)

2. 写入XML文件

在写入时,我觉得可分为两种方式:

新建一个全新的XML文件

在已有XML文件基础上追加一些元素信息

至于以上两种情况,其实创建元素结点的方法类似,你必须要做的都是先创建/得到一个DOM对象,再在DOM基础上创建new一个新的结点。

如果是第一种情况,你可以通过dom=minidom.Document()来创建;如果是第二种情况,直接可以通过解析已有XML文件来得到dom对象,例如dom = parse("./customer.xml")

在具体创建元素/文本结点时,你大致会写出像以下这样的“四部曲”代码:

①创建一个新元素结点createElement()

②创建一个文本节点createTextNode()

③将文本节点挂载元素结点上

④将元素结点挂载到其父元素上。

现在,我需要新建一个customer节点,信息如下:

<customer ID="C003">
  <name>kavin</name>
  <phone>32467</phone>
  <comments>
   <![CDATA[A small but healthy company.]]>
  </comments>
 </customer>

代码如下:

def writeXML():
 domTree = parse("./customer.xml")
 # 文档根元素
 rootNode = domTree.documentElement

 # 新建一个customer节点
 customer_node = domTree.createElement("customer")
 customer_node.setAttribute("ID", "C003")

 # 创建name节点,并设置textValue
 name_node = domTree.createElement("name")
 name_text_value = domTree.createTextNode("kavin")
 name_node.appendChild(name_text_value) # 把文本节点挂到name_node节点
 customer_node.appendChild(name_node)

 # 创建phone节点,并设置textValue
 phone_node = domTree.createElement("phone")
 phone_text_value = domTree.createTextNode("32467")
 phone_node.appendChild(phone_text_value) # 把文本节点挂到name_node节点
 customer_node.appendChild(phone_node)

 # 创建comments节点,这里是CDATA
 comments_node = domTree.createElement("comments")
 cdata_text_value = domTree.createCDATASection("A small but healthy company.")
 comments_node.appendChild(cdata_text_value)
 customer_node.appendChild(comments_node)

 rootNode.appendChild(customer_node)

 with open('added_customer.xml', 'w') as f:
 # 缩进 - 换行 - 编码
 domTree.writexml(f, addindent=' ', encoding='utf-8')

if __name__ == '__main__':
 writeXML()

python解析xml文件方式(解析、更新、写入)

3. 更新XML文件

在更新XML时,只需先找到对应的元素结点,然后将其下的文本结点或属性取值更新即可,然后保存到文件,具体我就不多说了,代码中我将思路都注释清楚了,如下:

def updateXML():
 domTree = parse("./customer.xml")
 # 文档根元素
 rootNode = domTree.documentElement

 names = rootNode.getElementsByTagName("name")
 for name in names:
 if name.childNodes[0].data == "Acme Inc.":
  # 获取到name节点的父节点
  pn = name.parentNode
  # 父节点的phone节点,其实也就是name的兄弟节点
  # 可能有sibNode方法,我没试过,大家可以google一下
  phone = pn.getElementsByTagName("phone")[0]
  # 更新phone的取值
  phone.childNodes[0].data = 99999

 with open('updated_customer.xml', 'w') as f:
 # 缩进 - 换行 - 编码
 domTree.writexml(f, addindent=' ', encoding='utf-8')

if __name__ == '__main__':
 updateXML()

python解析xml文件方式(解析、更新、写入)

如有不对之处,还烦请指教~

补充知识:python 读取xml文件内容并完成修改

我就废话不多说了,还是直接看代码吧!

import os
import xml.etree.ElementTree as ET


def changesku(inputpath):
  listdir = os.listdir(inputpath)
  for file in listdir:
    if file.endswith('xml'):
      file = os.path.join(inputpath,file)
      tree = ET.parse(file)
      root = tree.getroot()
      for object1 in root.findall('object'):   #我要修改的元素在object里面,所以需要先找到object
        for sku in object1.findall('name'):  #查找想要修改的所有同种元素
          if (sku.text == '005'):         #‘005'为原始的text
            sku.text = '008'           #修改‘name'的标签值
            tree.write(file,encoding='utf-8')   #写进原始的xml文件,不然修改就无效,‘encoding = “utf - 8”'避免原始xml                                           #中文字符乱码

          else:
            pass                  
    else:
      pass

if __name__ == '__main__':
  
  inputpath = 'D:\\easy\\hebing_xml'     #这是xml文件的文件夹的绝对地址
  changesku(inputpath)

以上这篇python解析xml文件方式(解析、更新、写入)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python with statement 进行文件操作指南
Aug 22 Python
Python实现SMTP发送邮件详细教程
Mar 02 Python
Python装饰器简单用法实例小结
Dec 03 Python
解决Python一行输出不显示的问题
Dec 03 Python
Django Rest framework之认证的实现代码
Dec 17 Python
Python3 列表,数组,矩阵的相互转换的方法示例
Aug 05 Python
详解python 利用echarts画地图(热力图)(世界地图,省市地图,区县地图)
Aug 06 Python
python字符串替换re.sub()方法解析
Sep 18 Python
python使用dlib进行人脸检测和关键点的示例
Dec 05 Python
Selenium执行完毕未关闭chromedriver/geckodriver进程的解决办法(java版+python版)
Dec 07 Python
python 调用js的四种方式
Apr 11 Python
Python 中的单分派泛函数你真的了解吗
Jun 22 Python
如何使用pandas读取txt文件中指定的列(有无标题)
Mar 05 #Python
python批量替换文件名中的共同字符实例
Mar 05 #Python
python批量修改xml属性的实现方式
Mar 05 #Python
python修改linux中文件(文件夹)的权限属性操作
Mar 05 #Python
Python实现在Windows平台修改文件属性
Mar 05 #Python
Pycharm最常用的快捷键及使用技巧
Mar 05 #Python
Python 去除字符串中指定字符串
Mar 05 #Python
You might like
无数据库的详细域名查询程序PHP版(3)
2006/10/09 PHP
Zend Guard一些常见问题解答
2008/09/11 PHP
php 服务器调试 Zend Debugger 的安装教程
2009/09/25 PHP
file_get_contents获取不到网页内容的解决方法
2013/03/07 PHP
php四种基础算法代码实例
2013/10/29 PHP
ThinkPHP中Widget扩展的两种写法及调用方法详解
2017/05/04 PHP
详解将数据从Laravel传送到vue的四种方式
2019/10/16 PHP
Javascript 面向对象 命名空间
2010/05/13 Javascript
javascript之Partial Application学习
2013/01/10 Javascript
javascrip关于继承的小例子
2013/05/10 Javascript
JS截取字符串常用方法详细整理
2013/10/28 Javascript
12种不宜使用的Javascript语法整理
2013/11/04 Javascript
IE下支持文本框和密码框placeholder效果的JQuery插件分享
2015/01/31 Javascript
JS+CSS实现可拖动的弹出提示框
2015/02/16 Javascript
学习JavaScript设计模式(封装)
2015/11/26 Javascript
使用jQuery加载html页面到指定的div实现方法
2016/07/13 Javascript
js实现下拉框效果(select)
2017/03/28 Javascript
Angular搜索场景中使用rxjs的操作符处理思路
2018/05/30 Javascript
详解vue 命名视图
2019/08/14 Javascript
Vue中错误图片的处理的实现代码
2019/11/07 Javascript
JavaScript实现简单贪吃蛇效果
2020/03/09 Javascript
JS出现404错误原理及解决方案
2020/07/01 Javascript
Python3安装Pillow与PIL的方法
2019/04/03 Python
pycharm配置当鼠标悬停时快速提示方法参数
2019/07/31 Python
Python全局锁中如何合理运用多线程(多进程)
2019/11/06 Python
python os.path.isfile 的使用误区详解
2019/11/29 Python
使用Matplotlib绘制不同颜色的带箭头的线实例
2020/04/17 Python
加拿大建筑和装修专家:Reno-Depot
2017/12/21 全球购物
如何判断一段程序是由C 编译程序还是由C++编译程序编译的
2013/08/04 面试题
经贸专业毕业生求职信
2014/03/23 职场文书
政府绩效管理实施方案
2014/05/04 职场文书
婚宴父母致辞
2015/07/27 职场文书
小学大队长竞选稿
2015/11/20 职场文书
小学教师师德培训心得体会
2016/01/09 职场文书
Nginx使用Lua模块实现WAF的原理解析
2021/09/04 Servers
详解Flutter网络请求Dio库的使用及封装
2022/04/14 Java/Android