背景

Python有三种方法解析xml:SAX,DOM,Elementree。本文记录ElementTree方法解析xml。
目前自己用的是Python3.6,但在该版本中并没有xml的缩进函数ET.indent,不过就我所知3.9版本是有的,所以当前3.6写出来的xml是无法调用函数来美化xml排版,文中的xml排版是手动挡 :)。当然,也可以写个函数来自动优化。

正文

xml是一种固有的分层数据格式,最好的描述方式就是使用树形结构。在ElementTree模块中,使用ElementTree对象来表示一棵树,Element对象来表示树中的一个单一结点。读取、写入一个xml文件一般都是在ElementTree层面上操作,而对xml元素(结点)及其子元素(子结点)的操作是在Element层面上进行。

说明:下面的内容有时候使用明确的node名称来代替Element进行操作,有时候使用Element泛指一个结点。ElementTree和Element是一个类,创建一棵树tree或者一个结点node相当于类的实例化。

解析xml文件

import xml.etree.ElementTree as ET   # 导入ElementTree模块
tree = ET.parse(xml_file_path)       # 解析xml文件,得到树形结构
root = tree.getroot()                # 获取根节点

结点基础:node.tag,node.attrib,node.get(),node.text

每个结点都有标签(tag)和属性(attrib),标签名一般不为空,属性可为空,比如:

<data, attrib=[]><daughter_node, name="child_1", age="20"><chichild_node>...</chichild_node></daughter_node>...<daughter_node>2021</daughter_node><son_node>...<son_node>...<son_node>...<son_node>
</data>

上面为一个根结点及其子结点的例子,根结点的标签名为data,没有属性(attrib为空:[])。注意区分结点的属性和结点的子结点,属性包含在结点的括号<>中,而子结点是夹在一对标签内。获取一个结点的标签和属性(此处结点为根节点):

root.tag              # 返回结点的标签名data
root.atrrib           # 返回结点的属性,此时根节点的属性为[]

而对于非空属性的结点,其属性可以单个或者多个,比如下面这个结点child node,它带有两个属性nameage

<child_node, name="child_1" age="20">...
</child_node>

可以使用如下代码来访问child_node属性:

child_node.attrib                    # 返回一个字典,字典包含每个属性名和属性内容
child_node.get("name")               # 返回name属性的属性内容:child_1

假定C结点(node结点)没有子结点,但夹有文本信息:

<node>2021</node>

则要获取node结点的文本信息,有:

node.text            # 返回“2021”

结点拔高:遍历,索引,遍历指定结点Element.iter(),查找指定结点Element.findall()

  • 有子结点的父结点是可迭代循环的,可以用for循环遍历父结点的所有子结点

    for child in root:print((child.tag, child.attrib))
    
  • 通过索引的方式获取结点

    node = root[0][1]
    

    此处表示返回root结点(A)的第0个子结点(B)的第1个子结点(C),ABC三个的关系是,A是B的父节点,A是C的爷爷节点,B是C的父节点。

  • 指定遍历某一类结点

    假定要遍历上面例子中data结点下的所有daughter_node,则可以使用Element.iter()来指定遍历结点:

    for daughter in data.iter("daughter_node"):print(daughter.tag)print(daughter.attrib)
    

    ps:可以用data.findall()替换data.iter(),进行同样的迭代,但区别在哪里自己探索吧。

创建xml并保存

  • 创建结点:ElementTree.Element()
  • 创建树形结构:ElementTree.ElementTree()
  • 保存为xml文件:ElementTree.write()
  • 添加子结点:ElementTree.append()

要创建xml文件,那首先就要创建一个树形结构,对于树形结构,肯定是在ElementTree这个层次上创建,相当于创建了一个树架子,而Element是创建结点,创建树架子和结点后,你需要将Element结点挂到树架子ElementTree上,因此:

xml_2_path = r"path\to\save\your\xml\file.xml"
root = ET.Element("data", {"year":"2021", "age":"21"})               # 创建根节点
new_tree = ET.ElementTree(element=root)                               # 创建树形结构,再将根节点传递到树中
child = ET.Element("child_1")                                        # 创建一个结点
child.text = "Anya"                                                  # 创界该结点的text内容
root.append(child)                                                  # 将该结点连接到根结点root,此时该结点便成了root的子结点
new_tree.write(xml_2_path)

修改xml

  • 修改文本:node.text = 2022
  • 修改属性:node.set()
  • 移除结点:Element.remove()
  • 查找特定结点:Element.findall()

假定目前已有xml文件如下:

<data, attrib=[]><daughter_node, name="child_1", age="20"><chichild_node>...</chichild_node></daughter_node>...<daughter_node>2021</daughter_node><son_node>...<son_node>...<son_node>...<son_node>
</data>
  • 对于创建的Element对象,可以通过直接对其结点域(fields)赋值,达到修改的目的,例如:

    daughter_node.text = 2022             # 原值为2021,经赋值后,当前值为2022
    
  • 对于一个结点的属性,可以使用Element.set()来新增或修改结点属性:

    data[0].set("age", "21")
    data[0].set("where", "home")
    

    data[0]代表data的第一个子结点daughter_node,有属性nameage,没有属性where,因此上面的代码第一条修改了age属性,将20修改为21;新增了属性where,其属性值为home。此时该节点有三个属性。

  • 假定当前for循环遍历所有son_node,删掉满足判断条件(此处为True)的son_node,那么:

    for one_son_node in data.findall("son_node"):if True:data.remove(one_son_node)
    

    注意,此处不能用data.iter()替代data.findall(),因为后者只是查找,返回的是查找的结果;而前者是迭代,如果在迭代的过程中修改,会导致迭代发生错误

保存修改后的xml树

在经过上面的一系列修改后,此时的xml文件里的内容并没有修改,因此需要将修改后的树重写进文件中:

ElementTree.write(r"path\to\save\your\xml\file.xml")

结语

写到到这里,自己完全明白了怎么建立树形结构、结点及两者的相关操作,能准确区分ElementTree和Element到底是什么。本文只讲了一些基础的操作,看完后完全可以自行进官网查看两者的文档,发觉更多其他更操作:

  • ElementTree
  • Element

「Python」 ElementTree模块解析xml文件,建议小白阅读全文相关推荐

  1. python中利用lxml模块解析xml文件报错XMLSyntaxError: Opening and ending tag mismatch

    今天在代码中第一次使用lxml解析xml文件时出错了, XMLSyntaxError: Opening and ending tag mismatch: keyEffectiveDate line 2 ...

  2. 应用python的docx模块解析word文件内容

    目录 工作问题 涉及知识点 实现过程 目标 调用对应的库和模块 定义通用方法 1.[遍历全部的同格式文件]返回一个文件夹内,限定某类格式文件,返回全部这类文件的绝对路径 2.[提取段落&表格中 ...

  3. python使用ElementTree解析XML文件

    一.将XML网页保存到本地 要加载XML文件首先应该将网页上的信息提取出来,保存为本地XML文件.抓取网页信息可以python的urllib模块. 代码如下: from urllib import u ...

  4. python解析xml文件选用模块_python语言解析xml文件的常用的有两种方式

    MiniDom方式解析xml xml文件以data.xml为例,具体操作如下: data.xml: 保存用户的信息 Jordy 12345678 20 男 上网 功夫 34443678 18 男 功夫 ...

  5. Python语言解析xml文件

    python语言解析xml文件的常用的有两种方式: 通过MiniDom库解析xml文件 通过ElementTree库解析xml文件 MiniDom方式解析xml xml文件以data.xml为例,具体 ...

  6. python解析xml文件选用模块_Python标准库系列之xml模块

    Python's interfaces for processing XML are grouped in the xml package. 带分隔符的文件仅有两维的数据:行和列.如果你想在程序之间交 ...

  7. python解析xml文件最好选用的模块_用Python解析XML文件

    本文翻译自:https://developer.yahoo.com/python/python-xml.html 使用Python解析XML文件 许多YDN APIs提供了JSON格式的数据输出,JS ...

  8. python解析xml文件最好选用的模块_python高级编程 之解析XML文件模块

    XML是啥?可扩展标记语言(extensible  makeup language),以.xml为后缀的文件. XML文件最大的作用在于存储和传输数据.很多Python的项目就是把产品相关配置参数存储 ...

  9. python解析xml文件elementtree_在python中使用ElementTree解析xml文件

    ElementTree是python自带的处理xml格式文件的模块,位于libxmletreeElementTree.py.这个模块有两个基本概念:Element和ElementTree. 表示整个树 ...

最新文章

  1. 转载大神的 Linux查看物理CPU个数、核数、逻辑CPU个数
  2. 树莓派人脸识别门禁opencv4.2_树莓派人脸识别实际应用:人脸识别门禁
  3. linux ext4 img解包打包教程,解打包.img.ext4(转)
  4. python合并两个有序列表_合并两个有序链表(Python3)
  5. mysql物流管理系统_wuliuwang 物流信息管理系统 ssh2 mysql(Logistics Information Management System) - 下载 - 搜珍网...
  6. RMAN备份filesperset用法
  7. mysql group原理_MySQL Group By 实现原理分析
  8. CSS3最颠覆性的动画效果,基本属性[3D]
  9. 用实力给自己正名,YOLOv5:道路损伤检测我最强!GRDDC'2020大赛报告
  10. linux grep (转)
  11. mysql从一个表查询插入另一个表存在时更新_漫谈MySQL的锁机制
  12. ThinkPHP如何URL如何去掉index.php(重写模式)
  13. 手撸一个基于Springboot+Vue的书籍论坛系统,可用于课程设计和毕业设计或者练手
  14. 产品 电信nb接口调用_NB-IOT开发流程---基于中国电信物联网平台实现平台对接
  15. 2017计算机办公自动化试题,2017年办公自动化考试试题及解答
  16. 2D纸娃娃系统的web演示
  17. android MediaRecorder录屏时带录音功能实现
  18. c语言 extern的作用
  19. 英语四级计算机准考证号查询,2016英语四级准考证号忘了怎么查成绩
  20. [SSL_CHX][2021-10-15]移动路线

热门文章

  1. VTK:循环布尔PolyData用法实战
  2. VTK:截锥体用法实战
  3. OpenCASCADE:写STEP
  4. wxHtml 示例:演示嵌入控件
  5. wxWidgets:wxMouseCaptureChangedEvent类用法
  6. wxWidgets:wxArchiveClassFactory类用法
  7. boost::detail::spinlock_pool相关的测试程序
  8. boost::disjoint_sets_with_storage用法的测试程序
  9. boost::gil模块数字扩展中的 resample_pixels() 示例
  10. GDCM:制作模板的测试程序