xml 模块

一、引入

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

xml模块介绍

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

二、xml文档模板

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

#此处data就是一个根节点,所有的country都是data的子节点,country下的标签又是country的子节点    
#此处country就是标签名(tag),name是属性名,Liechtenstein是值        
2
       
2008
       
141100
       
       
   
   
       
5
       
2011
       
59900
       
   
   
       
69
       
2011
       
13600
       
       
   

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

三、xml模块的用法

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

1、Python内XML树的增删改查

1.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)  # 
​# 读出顶级节点对象dateroot = tree.getroot()print(root)  #
​# 查找三种方式# 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)  # countryprint(res.attrib)  # {'name': 'Liechtenstein'}print(res.text)  # 文本内容为空​# 递归查找country下的year. 并获取其标签名, 属性, 文本内容res = root.find('country').find('year')  # 等同于接着上面的继续, res.find('year')print(res)  #
print(res.tag)  # yearprint(res.attrib)  # {'update': 'no'}print(res.text)  # 2018​# 3. 在root的子节点找所有: root.findall("country")res = root.findall("country")print(res)  # [
,
,
]​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'''

1.2修改

​import xml.etree.ElementTree as ET​tree = ET.parse('db.xml')root = tree.getroot()​# 需求: 把"db.xml"文件中的country所有year标签属性名改为no, 标签文本加10for 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标签文本加10000for gdppc in root.iter('gdppc'):    print(gdppc)    gdppc.text = str(int(gdppc.text) + 10000)​tree.write('db.xml')

1.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")

1.4删除

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

2/构建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"写入.

3、获取根

  • xml树示例

#此处data就是一个根节点,所有的country都是data的子节点,country下的标签又是country的子节点    
#此处country就是标签名(tag),name是属性名,Liechtenstein是值        
2
       
2008
       
141100
       
       
   
   
       
5
       
2011
       
59900
       
   

以上面的xml树获取根

import xml.etree.cElementTree as ET#import...as 是一种简写方式​tree = ET.parse("a.xml")#此处的aroot = tree.getroot()print(root)#会打印一个内存地址,相当于一个对象

4、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方法会获得所有的数字值即两个属性名中间存的值,例 
2011

.iter方法

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

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

参考资料