当前位置: 首页 > news >正文

Python之xml 模块详解

xml 模块

一、引入

xml即可扩展标记语言,它可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。**从结构上,很像HTML超文本标记语言。**但他们被设计的目的是不同的,超文本标记语言被设计用来显示数据,其焦点是数据的外观。它被设计用来传输和存储数据,其焦点是数据的内容。那么Python是如何处理XML语言文件的呢?下面一起来看看Python常用内置模块之xml模块吧。

xml模块介绍

xml是实现不同语言或程序之间进行数据交换的协议,功能跟json差不多,但json使用起来更简单,不过,古时候,在json还没诞生的黑暗年代,大家只能选择用xml呀,至今很多传统公司如金融行业的很多系统的接口还主要是xml。

二、xml文档模板

xml的格式如下,就是通过<>节点来区别数据结构的:

<?xml version="1.0"?>
<data>	#此处data就是一个根节点,所有的country都是data的子节点,country下的标签又是country的子节点
    <country name="Liechtenstein">	#此处country就是标签名(tag),name是属性名,Liechtenstein是值
        <rank updated="yes">2</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank updated="yes">5</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
    <country name="Panama">
        <rank updated="yes">69</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>

XML所用的标签语言又分为自闭和标签和非自闭和标签,自闭和标签只有在开头有tag,非自闭合标签在开头和结尾都有tag。
这是一个自闭和标签, 2</ rank>这是一个非自闭合标签。

三、xml模块的用法

xml协议在各个语言里的都 是支持的,在python中可以用ElementTree操作xml:ElementTree是python的XML处理模块,它提供了一个轻量级的对象模型。在使用ElementTree模块时,需要import xml.etree.ElementTree的操作。ElementTree表示整个XML节点树,而Element表示节点数中的一个单独的节点。

Python内XML树的增删改查

1、查看

"""
# 注意: 返回值都是对应的标签节点对象.
print(root.iter('year')) # 全文搜索
print(root.find('country')) # 在root的子节点找,只找一个
print(root.findall('country')) # 在root的子节点找,找所有(类始于subprocess中的找到所有sections)
"""
import xml.etree.ElementTree as ET  # 这样导入的好处就是xml和etree包中的功能都能直接使用. 同时三者可以结合使用

# 打开文件, 读出xml文件对象
tree = ET.parse('db.xml')  # 如上xml模板存入db.xml文件中
print(tree)  # <xml.etree.ElementTree.ElementTree object at 0x0000023703B24070>

# 读出顶级节点对象date
root = tree.getroot()
print(root)  # <Element 'data' at 0x0000023703C7E720>

# 查找三种方式
# 1. 全文搜索: root.iter('year') 
res = root.iter("year")
print(res)  # <_elementtree._element_iterator object at 0x0000023EE649DE50>

for year in res:
    print(''.center(50, '-'))
    print(year.tag)  # 获取year节点对象的标签名
    print(year.attrib)  # 获取year节点对象的属性. 以key:value对的形式输出. key代指属性名, value代指属性值
    print(year.text)  # 获取year节点对象中的文本内容.
"""
--------------------------------------------------
year
{'update': 'no'}
2018
--------------------------------------------------
year
{'update': 'no'}
2021
--------------------------------------------------
year
{'update': 'no'}
2021
"""

# 2. 在root的子节点找,只找一个: root.find('country')
res = root.find('country')
print(res.tag)  # country
print(res.attrib)  # {'name': 'Liechtenstein'}
print(res.text)  # 文本内容为空

# 递归查找country下的year. 并获取其标签名, 属性, 文本内容
res = root.find('country').find('year')  # 等同于接着上面的继续, res.find('year')
print(res)  # <Element 'year' at 0x000002A64D5BD590>
print(res.tag)  # year
print(res.attrib)  # {'update': 'no'}
print(res.text)  # 2018

# 3. 在root的子节点找所有: root.findall("country")
res = root.findall("country")
print(res)  # [<Element 'country' at 0x00000253D3A9E770>, <Element 'country' at 0x00000253D3ACD810>, <Element 'country' at 0x00000253D3ACDAE0>]

for country in res:
    print(''.center(50, '-'))
    res = country.find('year')
    print(res.tag)
    print(res.attrib)
    print(res.text)
'''
--------------------------------------------------
year
{'update': 'no'}
2018
--------------------------------------------------
year
{'update': 'no'}
2021
--------------------------------------------------
year
{'update': 'no'}
2021
'''

2、修改

import xml.etree.ElementTree as ET

tree = ET.parse('db.xml')
root = tree.getroot()

# 需求: 把"db.xml"文件中的country所有year标签属性名改为no, 标签文本加10
for year in root.iter('year'):
    print(year)
    year.text = str(int(year.text) + 10)  # 注意: "db.xml"使用year.text读出, 默认是字符串, 我们要使用int转换成整型才能进行数字运算.
    year.attrib = {'update': 'no'}

tree.write('db.xml')

# 需求:  把"db.xml"文件中的country下所有gdppc标签文本加10000
for gdppc in root.iter('gdppc'):
    print(gdppc)
    gdppc.text = str(int(gdppc.text) + 10000)

tree.write('db.xml')

3、增加

import xml.etree.ElementTree as ET

tree = ET.parse('db.xml')
root = tree.getroot()

for country in root.iter('country'):
    year = country.find("year")
    if int(year.text) > 2010:
        # 1. 调用ET.Element()方法增加标签, 属性, 文本
        flag = ET.Element('egon')  # 2. 添加标签
        flag.attrib = {'DSB': 'yes'} #  3. 为添加的flag标签对象添加属性
        flag.text = '大帅逼1'  # 4. 为添加的flag标签对象添加文本内容
        country.append(flag) # 5. 把添加的flag标签对象追加到country标签中, 作为country的子节点标签对象.(往country节点下添加子节点)

tree.write("db.xml")

4、删除

import xml.etree.ElementTree as ET

tree = ET.parse('db.xml')
root = tree.getroot()

# 需求: 在所有的country标签节点对象下的rank如果它的文本内容大于50, 那么就删除这个country
for country in root.findall('country'):
   rank = int(country.find('rank').text)
   if rank > 50:
     root.remove(country)
 
tree.write('db.xml')

构建xml文件

import xml.etree.ElementTree as ET

new_xml = ET.Element("country")  # 创建标签country节点, 返回new_xml节点对象
name = ET.SubElement(new_xml, "name", attrib={"update": "yes"})  # 在new_xml节点对象下创建标签名为"name"的子节点对象, 并指定属性
name.text = 'egon'  # 为"name"字节的点对象添加文本内容
age = ET.SubElement(new_xml, 'year', attrib={'update': 'no'})
age.text = '18'
sex = ET.SubElement(new_xml, 'sex')
sex.text = 'male'

et = ET.ElementTree(new_xml)  # 生成文档对象
et.write('text.xml', encoding='utf-8', xml_declaration=True)  # 创建文件, 将该文档对象"et"写入. 

获取根

  • xml树示例
<data>#此处data就是一个根节点,所有的country都是data的子节点,country下的标签又是country的子节点
    <country name = "Liechtenstein">#此处country就是标签名(tag),name是属性名,Liechtenstein是值
        <rank updated = "yes">2</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name ="Austria" direction ="E"/>
        <neighbor name ="Switzerland" direction = "W"/>
    </country>
    <country name ="Singapore">
        <rank updated="yes">5</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name ="Malaysia" direction="N"/>
    </country>
</data>

以上面的xml树获取根

import xml.etree.cElementTree as ET#import...as 是一种简写方式

tree = ET.parse("a.xml")#此处的a
root = tree.getroot()
print(root)#会打印一个内存地址,相当于一个对象

tagattribtext方法

import xml.etree.cElementTree as ET

tree = ET.parse("a.xml")
root = tree.getroot()
for i in root:
    print(i.tag)#tag方法会得到标签内容
    print(i.attrib)#attrib方法会得到属性名和属性值,以字典的形式显示
for i in root:
    for j in i:
        print(j.tag)
        print(j.attrib)
for i in root:
    for j in i :
        print(j.text)#text方法会获得所有的数字值即两个属性名中间存的值,例 <year>2011</year>

.iter方法

  • .iter方法可以实现只遍历其中的某一个节点

    tree = ET.parse("a.xml")
    root = tree.getroot()
    for node in root.iter("year"):#可以获得所有的year节点的内容
        print(node.tag,node.attrib,node.text)
    

参考资料

  • https://www.w3school.com.cn/xml/xml_intro.asp
  • https://blog.csdn.net/weixin_43690603/article/details/90765299

相关文章:

  • xml 模块
  • subprocess 模块(了解)
  • python之subprocess 模块(了解)
  • configparser 模块 (了解)
  • Python之configparser 模块 (了解)
  • python之struct 模块详解
  • 网络架构及其演变过程
  • 计算机操作系统概述
  • 计算机网络OSI七层协议
  • 计算机网络之VLAN简述
  • 计算机网络之子网划分
  • 计算机网络之DHCP工作过程的六个主要步骤
  • 计算机网络之洪水攻击
  • TCP协议的三次握手和四次挥手详解
  • 春招进大厂面试Linux,就这6个问题!
  • 分享的文章《人生如棋》
  • android图片蒙层
  • C++回声服务器_9-epoll边缘触发模式版本服务器
  • in typeof instanceof ===这些运算符有什么作用
  • js算法-归并排序(merge_sort)
  • laravel5.5 视图共享数据
  • LeetCode刷题——29. Divide Two Integers(Part 1靠自己)
  • Logstash 参考指南(目录)
  • SQLServer之创建数据库快照
  • WebSocket使用
  • 阿里云Kubernetes容器服务上体验Knative
  • 让你成为前端,后端或全栈开发程序员的进阶指南,一门学到老的技术
  • 深入浅出Node.js
  • 微信公众号开发小记——5.python微信红包
  • 我的面试准备过程--容器(更新中)
  • - 转 Ext2.0 form使用实例
  • 06-01 点餐小程序前台界面搭建
  • media数据库操作,可以进行增删改查,实现回收站,隐私照片功能 SharedPreferences存储地址:
  • FaaS 的简单实践
  • #### go map 底层结构 ####
  • %3cli%3e连接html页面,html+canvas实现屏幕截取
  • (11)MATLAB PCA+SVM 人脸识别
  • (3)选择元素——(17)练习(Exercises)
  • (翻译)terry crowley: 写给程序员
  • (附源码)springboot宠物管理系统 毕业设计 121654
  • (每日持续更新)jdk api之FileFilter基础、应用、实战
  • (三十五)大数据实战——Superset可视化平台搭建
  • (四)Android布局类型(线性布局LinearLayout)
  • ./mysql.server: 没有那个文件或目录_Linux下安装MySQL出现“ls: /var/lib/mysql/*.pid: 没有那个文件或目录”...
  • .describe() python_Python-Win32com-Excel
  • .NET 6 Mysql Canal (CDC 增量同步,捕获变更数据) 案例版
  • .net core 3.0 linux,.NET Core 3.0 的新增功能
  • .NET设计模式(8):适配器模式(Adapter Pattern)
  • /bin/rm: 参数列表过长"的解决办法
  • /使用匿名内部类来复写Handler当中的handlerMessage()方法
  • @取消转义
  • [ 隧道技术 ] cpolar 工具详解之将内网端口映射到公网
  • [51nod1610]路径计数
  • [android学习笔记]学习jni编程
  • [AutoSar]BSW_OS 01 priority ceiling protocol(PCP)