• 21天学习挑战赛——Python操作XML文件


    目录

    1. XML基础

    1.1 XML概念

    1.2 XML特点及应用

     1.3 XML文件格式

    2. Python解析XML文件

    2.1 ElemetntTree方式

    2.2 DOM方式

    3. Python写入XML文件 

    4. Python编辑XML文件


    ​⭐昨天真忙到太晚了,来不及发布文章,对不住自己。以后会尽可能按时更新文章...🌈

    活动地址:CSDN21天学习挑战赛

    1. XML基础

    1.1 XML概念

            XML(Extensible Markup language):可扩展标记语言。xml 是互联网数据传输得重要工具,它可以跨越互联网任何的平台,不受编程语言的限制,可以说它是一个拥有互联网最高级别通行证的数据携带者。xml 是当处理结构化文档信息中相当给力的技术,xml 有助于在服务器之间穿梭结构化数据,这使得开发人员更加得心应手地控制数据的存储和传输。

            xml 用于标记电子文件,使具有结构性的标记语言可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。 xml 是具有通用标记语言(SGML)的子集,非常适合Web传输。xml 提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据。

    1.2 XML特点及应用

    特点:

    • xml 与编程语言的开发平台无关。
    • 可以实现不用系统之间的数据交互。

    作用:

    • 配置应用程序和网站。
    • 数据交互。
    • Ajax 基石。

     1.3 XML文件格式

            与 HTML 类似,XML 是另一种将数据存储在标记之间的标记语言。它是人类可读可扩展的,也就是说,我们可以自由地定义自己的标记。XML 中属性、元素和标记与 HTML 中的类似。XML 文件可以有声明,也可以没有声明,但是,如果它有一个声明,那么它必须是 XML 文件的第一行。如:

    
    

             这个声明语句有三部分:版本、编码和独立性。版本说明正在使用的 XML 标准的版本;Encoding 表示在此文件中使用的字符编码类型;Standalone 告诉解析器是否要外部信息来解释 XML 文件的内容。

            XML 文件可以表示为:XML树。这个 XML 树从根元素(父元素)开始。这个根元素进一步分支到子元素。XML 文件的每个元素都是 XML 树中的一个节点。那些没有节点的元素是叶节点。

    XML 文件格式内容包括:声明、根元素、子元素、属性、命名空间、限定名。

    2. Python解析XML文件

    2.1 ElemetntTree方式

            ElementTree 模块提供了一个轻量级、Pythonic 的API,同时还有一个高效的C语言实现,即 xml.etree.cElementTree。与 DOM 相比,ET 的速度更快,API 使用更直接、方便。与 SAX 相比,ET.iterparse 函数同样提供了按需解析的功能,不会一次性在内存中读入整个文档。ET 的性能与 SAX 模块大致相仿,但是它的 API 更加高层次,用户使用器来更加便捷。

    Element 对象方法
    类方法说明
    Element.iter(tag=None)遍历该 Element 所有后代,也可以指定 tag 进行遍历寻找
    Element.iterfind(path, namespaces=None)根据 tag 或 path 查找所有的后代
    Element.itertext()遍历所有后代并返回 text 值
    Element.findall(path)

    查找当前元素下 rag 或 path 能够匹配的直系节点

    Element.findtext(path, defult=Nonr, namespaces=None)寻找第一个匹配子元素,返回其 text 值。匹配对象可以为 tag 或 path
    Element.text()获取当前元素的 text 值
    Element.get(key, defult=None)获取元素指定 key 对应的属性值,如果没有该属性,则返回 default 值
    Element.keys()返回元素属性名称列表
    Element.items()返回(name, value)列表
    Element.getchildren()获取所有子元素
    Element.getiterator(tag=None)Python3.2后使用,Element.iter(tag=None)
    Element.getiterator(self, tag=None)
    Element 属性方法
    方法名说明
    Element.tag节点名(tag)(str)
    Element.attrib属性(attribes)(dict)
    Element.text文本(text)(str)
    Element.tail附加文本(tail)(str)
    Element[:]子节点列表(list)

    在程序相同目录下创建 test.xml 文件,里面包括:

    1. <collection shelf="New Arrivals">
    2. <class className="1班">
    3. <code>2022001code>
    4. <number>10number>
    5. <teacher>小白teacher>
    6. class>
    7. <class className="2班">
    8. <code>2022002code>
    9. <number>20number>
    10. <teacher>小红teacher>
    11. class>
    12. <class className="3班">
    13. <code>2022003code>
    14. <number>30number>
    15. <teacher>小黑teacher>
    16. class>
    17. collection>

    ​用法举例:

    1. import xml.etree.ElementTree as ET
    2. #1.加载test.xml文档,并进行解析
    3. tree = ET.ElementTree(file='test.xml')
    4. #2.获取根元素
    5. root =tree.getroot()
    6. print(root) #输出:
    7. #3.根元素root是一个Element对象,打印其元素
    8. print(root.tag) #输出:collection
    9. print(root.attrib) #输出:{'shelf': 'New Arrivals'}
    10. #4.遍历根元素的直接子元素
    11. for child_of_root in root:
    12. print(child_of_root.tag, child_of_root.attrib)
    13. #输出:class {'className': '1班'}
    14. # class {'className': '2班'}
    15. # class {'className': '3班'}
    16. #5.通过索引值访问特定的子元素
    17. print(root[0].tag,root[0].attrib) #输出:class {'className': '1班'}

    分析:从上面的示例代码中,可以明显地发现,我们能够通过简单的遍历方法获取树中的所用元素。但是,由于这是十分常见的工作,ET 提供了一些简便的实现方法。

            Element 对象有一个 iter 方法,可以对某个元素对象之下所有的元素进行深度优先遍历(DFS)。ElementTree 对象同样也有这个方法。下面是查找 XML 文档中所有元素的最简单方法(这点方法和字典遍历类似):

    1. import xml.etree.ElementTree as ET
    2. #1.加载test.xml文档,并进行解析
    3. tree = ET.ElementTree(file='test.xml')
    4. for elem in tree.iter():
    5. print(elem.tag, elem.attrib)
    6. #输出:
    7. # collection {'shelf': 'New Arrivals'}
    8. # class {'className': '1班'}
    9. # code {}
    10. # number {}
    11. # teacher {}
    12. # class {'className': '2班'}
    13. # code {}
    14. # number {}
    15. # teacher {}
    16. # class {'className': '3班'}
    17. # code {}
    18. # number {}
    19. # teacher {}

            对树进行遍历时,iter 方法也可以接收 tag 名称,然后遍历所有具备所提供 tag 的元素;支持通过 XPath 查找元素;也可以查找所有具备某个 name 属性的 className元素:

    1. import xml.etree.ElementTree as ET
    2. #加载test.xml文档,并进行解析
    3. tree = ET.ElementTree(file='test.xml')
    4. #遍历所有节点名tag=teacher的元素
    5. for elem in tree.iter(tag='teacher'):
    6. print(elem.tag, elem.text)
    7. # 输出:teacher 小白
    8. # teacher 小红
    9. # teacher 小黑
    10. #通过XPath查找class下面teacher元素
    11. for elem in tree.iterfind('class/teacher'):
    12. print(elem.tag,elem.text)
    13. # 输出:teacher 小白
    14. # teacher 小红
    15. # teacher 小黑
    16. #查找所有具备class下className="1班"的元素
    17. for elem in tree.iterfind('class[@className="1班"]'):
    18. print(elem.tag,elem.attrib)
    19. # 输出:class {'className': '1班'}

    遍历 xml 文件中所有元素的完整解析代码如下:

    1. import xml.etree.ElementTree as ET
    2. #加载test.xml文档,并进行解析
    3. tree = ET.ElementTree(file='test.xml')
    4. print(type(tree)) #输出:
    5. #获取根元素
    6. root = tree.getroot()
    7. print(type(root)) #输出:
    8. print(root.tag) #输出:collection
    9. #遍历剩余所有元素
    10. for index,child in enumerate(root):
    11. print("第%s个%s元素, 属性:%s"%(index, child.tag, child.attrib))
    12. for i,child_child in enumerate(child):
    13. print("标签:%s,内容:%s"%(child_child.tag,child_child.text))
    14. # 输出:
    15. # 第0个class元素, 属性:{'className': '1班'}
    16. # 标签:code,内容:2022001
    17. # 标签:number,内容:10
    18. # 标签:teacher,内容:小白
    19. # 第1个class元素, 属性:{'className': '2班'}
    20. # 标签:code,内容:2022002
    21. # 标签:number,内容:20
    22. # 标签:teacher,内容:小红
    23. # 第2个class元素, 属性:{'className': '3班'}
    24. # 标签:code,内容:2022003
    25. # 标签:number,内容:30
    26. # 标签:teacher,内容:小黑

    2.2 DOM方式

            DOM(Document Object Model)将 XML 文档作为一棵树状结构进行分析,获取节点的内容以及相关属性,或是新增、删除和修改节点的内容。XML 解析器在加载 XML 文件后,DOM 模式将 XML 文件的元素视为一个树状结构的节点,一次性读入内存。

    用法举例:

    1. from xml.dom.minidom import parse
    2. #读取文件
    3. dom = parse('test.xml')
    4. #获取文档元素对象
    5. elem = dom.documentElement
    6. #获取class
    7. class_list_obj = elem.getElementsByTagName('class')
    8. print(class_list_obj) #输出:[, , ]
    9. print(type(class_list_obj)) #输出:
    10. for class_element in class_list_obj:
    11. #获取标签中内容
    12. code = class_element.getElementsByTagName('code')[0].childNodes[0].nodeValue
    13. number = class_element.getElementsByTagName('number')[0].childNodes[0].nodeValue
    14. teacher = class_element.getElementsByTagName('teacher')[0].childNodes[0].nodeValue
    15. print('code:',code,'number:',number,'teacher:',teacher)
    16. # 输出:
    17. # code: 2022001 number: 10 teacher: 小白
    18. # code: 2022002 number: 20 teacher: 小红
    19. # code: 2022003 number: 30 teacher: 小黑

    3. Python写入XML文件 

            doc.wirtexml() :生成xml文档,将创建的存在于内存中的xml文档写入本地硬盘中,这时才能看到新建的xml文档。

    函数语法:writexml(file, indent='', addindent='', newl='', encoding=None)

    参数说明:

    • file:要保存为的文件对象名
    • indent:根节点的缩进方式
    • addindent:子节点的缩进方式
    • newl:针对新行,指明换行方式
    • encoding:保存文件的编码方式

    用法举例:

    1. import xml.dom.minidom
    2. #1.在内存中创建一个空的文档
    3. doc = xml.dom.minidom.Document()
    4. #2.创建根元素
    5. root = doc.createElement('collection')
    6. #3.设置根元素的属性
    7. root.setAttribute('type','New Arrivals')
    8. #4.将根节点添加到文档对象中
    9. doc.appendChild(root)
    10. #5.创建子元素
    11. book = doc.createElement('book')
    12. #6.添加注释
    13. book.appendChild(doc.createElement('这是一条注释'))
    14. #7.设置子元素的属性
    15. book.setAttribute('语言','Python')
    16. #8.子元素中嵌套元素,并添加文本节点
    17. name = doc.createElement('name')
    18. name.appendChild(doc.createTextNode('Python基础'))
    19. price = doc.createElement('价格')
    20. price.appendChild(doc.createTextNode('99元'))
    21. number = doc.createElement('number')
    22. number.appendChild(doc.createTextNode('剩余66本'))
    23. #9.将子元素添加到book节点中
    24. book.appendChild(name)
    25. book.appendChild(price)
    26. book.appendChild(number)
    27. #10.将book节点添加到root根元素中
    28. root.appendChild(book)
    29. #5-10相同方法,创建子元素
    30. book = doc.createElement('book')
    31. #添加注释
    32. book.appendChild(doc.createElement('这是一条注释'))
    33. #设置子元素的属性
    34. book.setAttribute('语言','C++')
    35. #子元素中嵌套元素,并添加文本节点
    36. name = doc.createElement('name')
    37. name.appendChild(doc.createTextNode('C++程序设计'))
    38. price = doc.createElement('价格')
    39. price.appendChild(doc.createTextNode('56元'))
    40. number = doc.createElement('number')
    41. number.appendChild(doc.createTextNode('剩余100本'))
    42. #将子元素添加到book节点中
    43. book.appendChild(name)
    44. book.appendChild(price)
    45. book.appendChild(number)
    46. #将book节点添加到root根元素中
    47. root.appendChild(book)
    48. print(root.toxml())
    49. #输出:<这是一条注释/>Python基础<价格>99元剩余66本<这是一条注释/>C++程序设计<价格>56元剩余100本
    50. fp =open('./数据.xml','w',encoding='utf-8') #需要指定文件编码格式为 utf-8,不然notepad++中显示十六进制
    51. doc.writexml(fp, indent='',addindent='\t',newl='\n',encoding='utf-8')
    52. fp.close()

    生成的 数据.xml 文件如下图所示:

    4. Python编辑XML文件

            使用 Python 向现有的 数据.xml 文件中插入新的子元素。

    用法举例:

    1. import xml.dom.minidom
    2. from xml.dom.minidom import parse
    3. #对 书籍.xml 新增一个子元素
    4. xml_file = './数据.xml'
    5. #拿到根节点
    6. domTree = parse(xml_file)
    7. rootNote = domTree.documentElement
    8. #2.1在内存中创建一个空的文档
    9. doc = xml.dom.minidom.Document()
    10. #2.2创建子元素
    11. book = doc.createElement('book')
    12. #2.3添加注释
    13. book.appendChild(doc.createElement('这是一条注释'))
    14. #2.4设置子元素的属性
    15. book.setAttribute('语言','matlab')
    16. #2.5子元素中嵌套元素,并添加文本节点
    17. name = doc.createElement('name')
    18. name.appendChild(doc.createTextNode('matlab基础'))
    19. price = doc.createElement('价格')
    20. price.appendChild(doc.createTextNode('69元'))
    21. number = doc.createElement('number')
    22. number.appendChild(doc.createTextNode('剩余96本'))
    23. #2.6将子元素添加到book节点中
    24. book.appendChild(name)
    25. book.appendChild(price)
    26. book.appendChild(number)
    27. #3.找到C++所在位置
    28. C_book = rootNote.getElementsByTagName('book')[1]
    29. #4.insertBefore方法,父节点.insertBefore(新节点,父节点中的子节点)
    30. # rootNote.insertBefore(book,C_book)
    31. #5.appendChild将新产生的子元素在最后插入
    32. rootNote.appendChild(book)
    33. print(rootNote.toxml())
    34. with open(xml_file, 'w', encoding='utf-8') as f:
    35. domTree.writexml(f, indent='',addindent='\t', newl='',encoding='utf-8')
    36. # 输出:
    37. #
    38. #
    39. # <这是一条注释/>
    40. # Python基础
    41. # <价格>99元
    42. # 剩余66本
    43. #
    44. #
    45. # <这是一条注释/>
    46. # C++程序设计
    47. # <价格>56元
    48. # 剩余100本
    49. #
    50. # <这是一条注释/>matlab基础<价格>69元剩余96本

    最终得到的 数据.xml 文件如下图所示: 

    分析:第4和5步代码只能执行一步,默认为后面有效。在 xml 文件中新加入的数据存在格式不统一问题,需要使用 from lxml import etree 模块进行解决。

  • 相关阅读:
    QT学习(1)
    【大语言模型LLM】-大语言模型如何编写Prompt?
    桥梁模板人工费多少钱?
    Python函数式编程(一)概念和itertools
    Linux目录操作
    UML类图以及常用集合
    【蓝桥·算法双周赛】蓝桥杯官方双周赛震撼来袭
    Ubuntu20.04以上 如何清理内存遇到报错如何处理[WARN]Free memory 1234(M)may be NOT ENOUGH
    亚马逊美国站TEMU跳舞毯CPC认证检测项目分析
    webpack5入门教程
  • 原文地址:https://blog.csdn.net/m0_52162042/article/details/126186996