• 技术学习:Python(05)|操作XML



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

    🏮1 XML概述

    🎈1.1 XML简介

    在这里插入图片描述

    • 定义:XML 指可扩展标记语言(eXtensible Markup Language)。可扩展标记语言(英语:Extensible Markup Language,简称:XML)是一种标记语言,是从标准通用标记语言(SGML)中简化修改出来的。它主要用到的有可扩展标记语言、可扩展样式语言(XSL)、XBRL和XPath

    • 用途:传输和存储数据。

    • 特点:与开发语言的操作系统无关,可跨平台实现操作系统间的通信。

    • 具象描述:可扩展标记语言;很像HTML的标记语言;设计宗旨是传输数据,而不是显示数据;XML 标签没有被预定义;可以自定义标签对;被设计为具有自我描述性;W3C 的推荐标准。

    🎈1.2 XML语法

    XML的一个小例子,可以参考上一节学习的内容。

    
    <person>
    	<name>小明name>
    	<sex>sex>
    	<age>18age>
    person>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    声明(可选择项)
    从上面代码中可以看到,一个XML包含一个声明

    标签
    必须有一个关闭标签。简单来说,XML必须有开始标签和结束标签,而且标签对的名称对大小写敏感。

    属性值
    属性值必须使用引号引起来。例如class="red"red就要使用引号括起来,如下:

    <person class="red">
    	<name>张三name>
    person>
    
    • 1
    • 2
    • 3

    特殊转义符

    转义后转义前解释
    <<less than
    >>greater than
    &&ampersand
    ''apostrophe
    ""quotation mark

    注释

    
    <person>
    	<name>张三name>
    	<age>18age>
    <person>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    🏮2 Python解析XML

    从上面的学习中,我已经了解什么是XML,下面就开始使用Python来解析XML文件。Python 有三种方法解析 XML,他们是SAXDOM,以及 ElementTree

    🎈2.1 解析XML方式&实验文件

    1. SAX (simple API for XML )【流式读取,需自定义回调函数
      Python 标准库包含 SAX 解析器,SAX 用事件驱动模型,通过在解析XML的过程中触发一个个的事件并调用用户定义的回调函数来处理XML文件。
    2. DOM(Document Object Model)【不建议使用,慢,占用内存
      将 XML 数据在内存中解析成一个树,通过对树的操作来操作XML。
    3. ElementTree(元素树)
      ElementTree就像一个轻量级的DOM,具有方便友好的API。代码可用性好,速度快,消耗内存少。

    比如,这里是一份xml文件persons.xml

    
    <persons>
    	<person sid="001">
    		<name>张小帅name>
    		<sex>sex>
    		<age>18age>
    	person>
    	<person sid="002">
    		<name>刘晓萌name>
    		<sex>sex>
    		<age>21age>
    	person>
    	<person sid="003">
    		<name>王老四name>
    		<sex>sex>
    		<age>38age>
    	person>
    persons>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    🎈2.2 SAX解析xml

    SAX是一种基于事件驱动的 API。利用SAX解析XML文档牵涉到两个部分: 解析器事件处理器

    将下面的内容写在一个SaxPersons.py文件中,

    #!/usr/bin/python
    # -*- coding: UTF-8 -*-
     
    import xml.sax
     
    class PersonHandler( xml.sax.ContentHandler ):
       def __init__(self):
          self.CurrentData = ""
          self.name = ""
          self.sex = ""
          self.age = ""
     
       # 开始元素事件
       def startElement(self, tag, attributes):
          self.CurrentData = tag
          if tag == "person":
             print ("*****person*****")
             sid = attributes["sid"]
             print ("编号:", sid)
     
       # 结束元素事件
       def endElement(self, tag):
          if self.CurrentData == "name":
             print ("姓名:", self.name)
          elif self.CurrentData == "sex":
             print ("性别:", self.sex)
          elif self.CurrentData == "age":
             print ("年龄:", self.age )     
          self.CurrentData = ""
     
       # 元素内容事件处理
       def characters(self, content):
          if self.CurrentData == "name":
             self.name = content
          elif self.CurrentData == "sex":
             self.sex = content
          elif self.CurrentData == "age":
             self.age = content
      
    if ( __name__ == "__main__" ):
       
       # 创建一个 XMLReader 对象
       parser = xml.sax.make_parser()
       
       # 打开一个执行空间
       parser.setFeature(xml.sax.handler.feature_namespaces, 0)
     
       # 重写 ContextHandler 指向我们自定义的执行器``PersonHandler``
       Handler = PersonHandler()
       parser.setContentHandler( Handler )
       
       # 解析转换指定路径上的XML文件
       parser.parse("persons.xml")
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    在Python3环境下,执行命令python3 SaxPersons.py解析结果如下:

    xxx$ python3 SaxPersons.py
    
    *****person*****
    编号: 001
    姓名: 张小帅
    性别: 男
    年龄: 18
    *****person*****
    编号: 002
    姓名: 刘晓萌
    性别: 女
    年龄: 21
    *****person*****
    编号: 003
    姓名: 王老四
    性别: 男
    年龄: 38
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    🔑 Python官方提供了针对SAX2的解析支持: https://docs.python.org/3/library/xml.sax.html

    🎈2.3 DOM(xml.dom)解析xml

    python中用xml.dom.minidom来解析xml文件。

    下面,我们使用persons.xml作为实验对象,来解析xml。下面是我们的python文件DomPersons.py

    #!/usr/bin/python
    # -*- coding: UTF-8 -*-
    
    from xml.dom.minidom import parse
    import xml.dom.minidom
     
    # 使用minidom解析器打开 XML 文档
    DOMTree = xml.dom.minidom.parse("persons.xml")
    collection = DOMTree.documentElement
    if collection.hasAttribute("shelf"):
       print ("根元素 : %s" % collection.getAttribute("shelf"))
     
    # 在集合中获取所有同学
    persons = collection.getElementsByTagName("person")
     
     # 遍历同学信息
    for person in persons:
       print ("*****person*****")
       if person.hasAttribute("sid"):
          print ("编号: %s" % person.getAttribute("sid"))
     
       name = person.getElementsByTagName('name')[0]
       print ("姓名: %s" % name.childNodes[0].data)
       
       sex = person.getElementsByTagName('sex')[0]
       print ("性别: %s" % sex.childNodes[0].data)
       
       age = person.getElementsByTagName('age')[0]
       print ("年龄: %s" % age.childNodes[0].data)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    在Python3环境下,执行python3 DomPersons.py解析结果如下:

    xxx$ python3 DomPersons.py
    *****person*****
    编号: 001
    姓名: 张小帅
    性别: 男
    年龄: 18
    *****person*****
    编号: 002
    姓名: 刘晓萌
    性别: 女
    年龄: 21
    *****person*****
    编号: 003
    姓名: 王老四
    性别: 男
    年龄: 38
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    🔑 Python官方提供解析支持: https://docs.python.org/3/library/xml.dom.html

    🎈2.4 ElementTree解析xml

    警告:该xml.etree.ElementTree模块对恶意构建的数据不安全。如果您需要解析不受信任或未经身份验证的数据,请参阅XML 漏洞

    当然,我们还是使用上面的persons.xml文件来作为我们的实验对象。下面是我们的python文件ElePersons.py

    #!/usr/bin/python
    # -*- coding: UTF-8 -*-
     
    import xml.etree.ElementTree as ET
    
    # 导入文件到python对象,也可以一步到位,直接使用``persons = ET.fromstring(country_data_as_string) ``,这个代码同下面两行等价
    tree = ET.parse('persons.xml')
    persons = tree.getroot()
    
    # 迭代子节点 
    for index, person in enumerate(persons):
        print ("第%s个%s同学,编号:%s" % (index, person.tag, person.attrib))
    
        # 子节点是嵌套的,使用索引来获取
        for i, p in enumerate(person):
            print ("标签名称:%s,标签内容:%s" % (p.tag, p.text))
            
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在Python3环境下,执行python3 ElePersons.py解析结果如下:

    xxx$ python3 ElePersons.py
    第0个person同学,编号:{'sid': '001'}
    标签名称:name,标签内容:张小帅
    标签名称:sex,标签内容:男
    标签名称:age,标签内容:181个person同学,编号:{'sid': '002'}
    标签名称:name,标签内容:刘晓萌
    标签名称:sex,标签内容:女
    标签名称:age,标签内容:212个person同学,编号:{'sid': '003'}
    标签名称:name,标签内容:王老四
    标签名称:sex,标签内容:男
    标签名称:age,标签内容:38
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    🎈2.5 ElementTree 详细解析

    🛎语法格式
    xml.etree.ElementTree.Element(tag, attrib={}, **extra)

    🩸 tag
    一个字符串,用于标识此元素表示的数据类型(简单说就是元素类型)。例如在我们上面的解析过程中,我们使用persons获取对象后,获取他的标签对是persons

    >>> import xml.etree.ElementTree as ET
    >>> persons = ET.parse('persons.xml').getroot()
    >>> print (persons.tag)
    persons
    
    • 1
    • 2
    • 3
    • 4

    在嵌套的对象中,我们使用迭代元素之后,可以循环遍历这个对象的标签,如下所示,其中使用了Python中的内置函数enumerate,该函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中:

    >>> for index, person in enumerate(persons):
    ...     print (person.tag)
    ...
    person
    person
    person
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    🔑 关于Python内置函数,可以参考官方提供文档:https://docs.python.org/release/3.10.4/library/functions.html

    🩸 attrib
    元素属性的字典。下面获取每个同学的属性,学籍编号,如下面所示:

    >>> for index, person in enumerate(persons):
    ...     print (person.attrib)
    ...
    {'sid': '001'}
    {'sid': '002'}
    {'sid': '003'}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    🩸 text
    标签对的内容。从下面的代码中,可以看到。text是针对标签对的内容或值。

    >>> for index, person in enumerate(persons):
    ...     for pi, p in enumerate(person):
    ...         print (p.tag)
    ...         print (p.text)
    ...         print ("------------")
    ...
    name
    张小帅
    ------------
    sex
    男
    ------------
    age
    18
    ------------
    name
    刘晓萌
    ------------
    sex
    女
    ------------
    age
    21
    ------------
    name
    王老四
    ------------
    sex
    男
    ------------
    age
    38
    ------------
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    🤔 思考:如果我想要打印出来persons这个对象的text内容,将会是什么呢,有兴趣的可以尝试下?

    🔑 Python官方提供解析支持:https://docs.python.org/release/3.9.9/library/xml.etree.elementtree.html#module-xml.etree.ElementTree

  • 相关阅读:
    项目验收报告 和 项目总结
    解决Kibana初始化失败报错: Unable to connect to Elasticsearch
    警惕超范围采集隐私-移动APP违规十宗罪
    安卓APP源码和设计报告——体育馆预约系统
    【C++】哈希表
    快收下这份拼接视频方法攻略,制作出你想要的视频
    【Go语言如何用 interface 实现多态】
    Golang slice 通过growslice调用nextslicecap计算扩容
    【Matplotlib绘制图像大全】(十六):Matplotlib绘制虚线折线图
    docker 容器中安装cron,却无法启动定时任务
  • 原文地址:https://blog.csdn.net/L_Lycos/article/details/126187047