前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >技术学习:Python(05)|操作XML

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

作者头像
艾特
发布2023-10-10 14:47:37
1970
发布2023-10-10 14:47:37

🏮1 XML概述

🎈1.1 XML简介

  • 定义:XML 指可扩展标记语言(eXtensible Markup Language)。可扩展标记语言(英语:Extensible Markup Language,简称:XML)是一种标记语言,是从标准通用标记语言(SGML)中简化修改出来的。它主要用到的有可扩展标记语言、可扩展样式语言(XSL)、XBRL和XPath等
  • 用途:传输和存储数据。
  • 特点:与开发语言的操作系统无关,可跨平台实现操作系统间的通信。
  • 具象描述:可扩展标记语言;很像HTML的标记语言;设计宗旨是传输数据,而不是显示数据;XML 标签没有被预定义;可以自定义标签对;被设计为具有自我描述性;W3C 的推荐标准。

🎈1.2 XML语法

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

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<person>
	<name>小明</name>
	<sex>男</sex>
	<age>18</age>
</person>

声明(可选择项) 从上面代码中可以看到,一个XML包含一个声明<?xml version="1.0" encoding="utf-8"?>

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

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

代码语言:javascript
复制
<person class="red">
	<name>张三</name>
</person>

特殊转义符

转义后

转义前

解释

&lt;

<

less than

&gt;

>

greater than

&amp;

&

ampersand

&apos;

'

apostrophe

&quot;

"

quotation mark

注释

代码语言:javascript
复制
<!-- 这是一个人对象 -->
<person>
	<name>张三</name>
	<age>18</age>
<person>

🏮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

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<persons>
	<person sid="001">
		<name>张小帅</name>
		<sex>男</sex>
		<age>18</age>
	</person>
	<person sid="002">
		<name>刘晓萌</name>
		<sex>女</sex>
		<age>21</age>
	</person>
	<person sid="003">
		<name>王老四</name>
		<sex>男</sex>
		<age>38</age>
	</person>
</persons>

🎈2.2 SAX解析xml

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

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

代码语言:javascript
复制
#!/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")

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

代码语言:javascript
复制
xxx$ python3 SaxPersons.py

*****person*****
编号: 001
姓名: 张小帅
性别: 男
年龄: 18
*****person*****
编号: 002
姓名: 刘晓萌
性别: 女
年龄: 21
*****person*****
编号: 003
姓名: 王老四
性别: 男
年龄: 38

🔑 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

代码语言:javascript
复制
#!/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)

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

代码语言:javascript
复制
xxx$ python3 DomPersons.py
*****person*****
编号: 001
姓名: 张小帅
性别: 男
年龄: 18
*****person*****
编号: 002
姓名: 刘晓萌
性别: 女
年龄: 21
*****person*****
编号: 003
姓名: 王老四
性别: 男
年龄: 38

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

🎈2.4 ElementTree解析xml

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

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

代码语言:javascript
复制
#!/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))

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

代码语言:javascript
复制
xxx$ python3 ElePersons.py
第0个person同学,编号:{'sid': '001'}
标签名称:name,标签内容:张小帅
标签名称:sex,标签内容:男
标签名称:age,标签内容:18
第1个person同学,编号:{'sid': '002'}
标签名称:name,标签内容:刘晓萌
标签名称:sex,标签内容:女
标签名称:age,标签内容:21
第2个person同学,编号:{'sid': '003'}
标签名称:name,标签内容:王老四
标签名称:sex,标签内容:男
标签名称:age,标签内容:38

🎈2.5 ElementTree 详细解析

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

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

代码语言:javascript
复制
>>> import xml.etree.ElementTree as ET
>>> persons = ET.parse('persons.xml').getroot()
>>> print (persons.tag)
persons

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

代码语言:javascript
复制
>>> for index, person in enumerate(persons):
...     print (person.tag)
...
person
person
person

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

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

代码语言:javascript
复制
>>> for index, person in enumerate(persons):
...     print (person.attrib)
...
{'sid': '001'}
{'sid': '002'}
{'sid': '003'}

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

代码语言:javascript
复制
>>> 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
------------

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

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-08-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 🎈1.1 XML简介
  • 🎈1.2 XML语法
  • 🏮2 Python解析XML
    • 🎈2.1 解析XML方式&实验文件
      • 🎈2.2 SAX解析xml
        • 🎈2.3 DOM(xml.dom)解析xml
          • 🎈2.4 ElementTree解析xml
            • 🎈2.5 ElementTree 详细解析
            相关产品与服务
            多因子身份认证
            多因子身份认证(Multi-factor Authentication Service,MFAS)的目的是建立一个多层次的防御体系,通过结合两种或三种认证因子(基于记忆的/基于持有物的/基于生物特征的认证因子)验证访问者的身份,使系统或资源更加安全。攻击者即使破解单一因子(如口令、人脸),应用的安全依然可以得到保障。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档