xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过在json还没诞生的黑暗年代,大家只能选择用xml呀,至今很多传统公司如金融行业的很多系统的接口还主要是xml。
xml的格式如下,就是通过<>节点来区别数据结构的:
<?xml version="1.0"?> <data> #父标签data <country name="china"> #子标签country 属性name="china" <rank updated="yes">2</rank> #子子标签rank 属性update="yes" 内容2 <year>2018</year> </country> </data>
xml协议在各个语言里的都 是支持的,在python中可以用以下模块操作xml:
import xml.etree.ElementTree as et #xml模板应该是最长的的模板了,可以用as简写为et(自定义) tree = et.parse('xml_lesson.xml') #用parse()方法来解析xml文件,拿到tree这个对象 root = tree.getroot() #getroot()拿到根节点 print(root.tag) #根节点的标签:data for i in root: #遍历一级子节点,即<country name='china'> print(i.tag) #子节点的标签:country print(i.attrib) #子节点的属性:{'name': 'china'} print(i.text) #子节点的内容:无,但实际上是一行空行,注意看下面的结果 for j in i: #遍历二级子节点,即<rank updated="yes">2</rank>和<year>2018</year> print(j.tag) #rank、year print(j.attrib) #{'updated': 'yes'}、{} print(j.text) #2、2018
结果:
data
country
{'name': 'china'}
rank
{'updated': 'yes'}
2
year
{}
2018
也可以通过直接找节点的方式遍历:
import xml.etree.ElementTree as et tree = et.parse('xml_lesson.xml') root = tree.getroot() for node in root.iter('rank'): #通过root.iter()方法直接找节点的标签,无论是第几层的节点都可找到,有几个找几个 print(node.tag,node.attrib,node.text)
结果:rank {'updated': 'yes'} 2
修改节点的操作:
import xml.etree.ElementTree as et tree = et.parse('xml_lesson.xml') root = tree.getroot() for node in root.iter('year'): new_year = int(node.text) + 1 #node.text为字符串,需要转为int node.text = str(new_year) #修改year节点的内容,需要转为str node.set('update','no') #修改year节点属性,用set()方法 tree.write('xml_lesson.xml') #最后需要写入,这里其实是新建一个文件,如果文件名和之前相同,那就是覆盖
结果:xml_lesson.xml变为:
<data>
<country name="china">
<rank updated="yes">2</rank>
<year update="no">2019</year>
</country>
</data>
删除节点的操作:
xml_lesson.xml为: <data> <country name="china"> <rank updated="yes">2</rank> <year update="no">2019</year> </country> <country name="India"> <rank updated="yes">47</rank> <year update="no">2019</year> </country> </data>
需求:把排名高于10的国家删除
import xml.etree.ElementTree as et tree = et.parse('xml_lesson.xml') root = tree.getroot() for country in root.findall('country'): #findall()找到所有country节点 rank = int(country.find('rank').text) #在每一个country节点下面,find()找到rank节点 if rank > 10: root.remove(country) #root.remove()删除country节点,注意不是删除rank节点 tree.write('abc.xml')
另一种写法:
for country in root.iter('country'): for rank in country.iter('rank'): # rank = int(country.find('rank').text) if int(rank.text) > 10: root.remove(country) tree.write('222.xml')
最后,创建xml文档:
import xml.etree.ElementTree as ET new_xml = ET.Element("namelist") #生成根节点,tag为namelist name = ET.SubElement(new_xml, "name", attrib={"enrolled": "yes"}) #生成一级子节点,第一个参数是上一级节点,tag为name,有一个属性 age = ET.SubElement(name, "age", attrib={"checked": "no"}) #生产二级子节点,第一个参数是上一级节点,tag是age,有一个属性 sex = ET.SubElement(name, "sex") sex.text = '33' #二级子节点的内容为'33' name2 = ET.SubElement(new_xml, "name", attrib={"enrolled": "no"}) age = ET.SubElement(name2, "age") age.text = '19' et = ET.ElementTree(new_xml) # 生成文档对象 et.write("test.xml", encoding="utf-8", xml_declaration=True) #写入
结果生成的test.xml文件:
<?xml version='1.0' encoding='utf-8'?> <namelist> <name enrolled="yes"> <age checked="no" /> <sex>33</sex> </name> <name enrolled="no"> <age>19</age> </name> </namelist>