Python中XML文件的处理(非常详细)
XML 格式虽然比 JSON 格式复杂,但是作为一种常用的数据格式,在物联网应用中依然很常见,熟悉 Python 对 XML 文件的操作是非常有必要的。
Python 对 XML 文件的操作方法主要有三种:DOM、SAX 及 ElementTree:
以上步骤的完整代码为:
findall() 方法用于查找指定的所有节点,即:
1) 导入ElementTree模块:
流程的完整代码为:
修改 XML 文件的流程如下:
1) 导入 ElementTree 模块:
流程的完整代码为:
XML文件简介
XML(可扩展性标记语言)是一种非常常用的文件类型,主要用于存储和传输数据。XML 文件的格式为:<zoo> <animal id='1'> <name>dog</name> <age>2</age> </animal> <animal id='2'> <name>tiger</name> <age>3</age> </animal> </zoo>XML文件有下列特征:
- 由标签对组成:<zoo></zoo>;
- 标签可以有属性:<animal id='1'>;
- 标签对可以嵌入数据:<name>dog</name>;
- 标签可以嵌入子标签,具有层级关系,即:
<zoo> <animal></animal> </zoo>
Python 对 XML 文件的操作方法主要有三种:DOM、SAX 及 ElementTree:
- DOM 把整个 XML 文件读入内存并解析为树,缺点是占用内存大、解析慢,优点是可以任意遍历树的节点。
- SAX 是流模式,边读边解析,占用内存小,解析快,缺点是需要自己处理事件。SAX 模块牺牲了便捷性,换取了速度和内存占用,是一个基于事件的API。意味着,它可以“在空中”处理庞大的文件,不用完全加载进内存。
- xml.etree.ElementTree 模块(简称 ET)提供了轻量级 Python 式的 API,相对于 DOM 来说,快了很多,而且有很多 API 可以使用,相对于 SAX 来说,ET.iterate 也提供了“在空中”的处理方式,没有必要加载整个文件到内存,性能与 SAX 差不多,API 的效率更高一点,使用起来很方便。
Python解析XML文件
准备一个名为 zoo.xml 的 XML 文件,完整内容为:<?xml version="1.0" encoding="utf-8"?> <zoo> <animal id='1'> <name>dog</name> <age>2</age> </animal> <animal id='2'> <name>tiger</name> <age>3</age> </animal> </zoo>首先导入 ElementTree 模块,即:
import xml.etree.ElementTree as ET加载 zoo.xml 文件,即:
root = ET.parse('zoo.xml')通过 getiterator() 获取指定节点,即:
animal_node = root.getiterator("animal")利用 getchildren() 获取子节点,并将标签和值打印出来,即:
for node in animal_node: animal_node_child = node.getchildren()[0] print(animal_node_child.tag+':'+animal_node_child.text)element 对象的标签、属性和值如下:
标签=element.tag; 属性=element.attrib; 值=element.text
以上步骤的完整代码为:
import xml.etree.ElementTree as ET root = ET.parse('zoo.xml') animal_node = root.getiterator("animal") for node in animal_node: animal_node_child = node.getchildren()[0] print(animal_node_child.tag+':'+animal_node_child.text)运行结果为:
name:dog
name:tiger
1) find()和findall()方法
find() 方法用于查找指定的第一个节点,即:import xml.etree.ElementTree as ET root = ET.parse('zoo.xml') zoo_find=root.find('animal') for note in zoo_find: print(note.tag+':'+note.text)运行后,可打印出第一个 animal 的所有内容,即:
name:dog
age:2
findall() 方法用于查找指定的所有节点,即:
import xml.etree.ElementTree as ET root = ET.parse('zoo.xml') zoo=root.findall('animal') for zoo_animal in zoo: for note in zoo_animal: print(note.tag+':'+note.text)运行后,可打印出所有 animal 标签的内容,即:
name:dog
age:2
name:tiger
age:3
Python创建和修改XML文件
除了需要解析 XML 文件,有时候还需要修改 XML 文件中的内容或创建一个 XML 文件。ElementTree 模块提供了这样的支持。1、创建XML文件
使用 ElementTree 模块创建XML文件的流程如下:1) 导入ElementTree模块:
import xml.etree.ElementTree as ET2) 创建根节点:
root = ET.Element("root")3) 创建子节点 sub1,并为其添加属性:
sub1 = ET.SubElement(root,"sub1") sub1.attrib = {"attribute":"sub1 attribute"}4) 创建子节点 sub2,并为其添加数据:
sub2 = ET.SubElement(root,"sub2") sub2.text = "new xml"5) 创建子节点 sub3,并为其添加数据:
sub3 = ET.SubElement(root,"sub3") sub3.text = "sub3 value"6) 创建 elementtree 对象,并写入文件:
tree = ET.ElementTree(root) tree.write("new.xml")
流程的完整代码为:
import xml.etree.ElementTree as ET root = ET.Element("root") sub1 = ET.SubElement(root,"sub1") sub1.attrib = {"attribute":"sub1 attribute"} sub2 = ET.SubElement(root,"sub2") sub2.text = "new xml" sub3 = ET.SubElement(root,"sub3") sub3.text = "sub3 value" tree = ET.ElementTree(root) tree.write("new.xml")运行后,会在当前目录下生成 new.xml 文件,内容为:
<root> <sub1 attribute="sub1 attribute" /> <sub2>new xml</sub2> <sub3>sub3 value</sub3> </root>调整一下格式,也就是:
<root> <sub1 attribute="sub1 attribute" /> <sub2>new xml</sub2> <sub3>sub3 value</sub3> </root>
2、修改XML文件
ElementTree 模块提供了多种修改 XML 文件的方法:- ElementTree.write("xmlfile"):更新 XML 文件;
- Element.append():为当前的 element 对象添加子元素(element);
- Element.set(key, value):为当前 element 的 key 属性设置 value 值;
- Element.remove(element):删除为 element 的节点。
修改 XML 文件的流程如下:
1) 导入 ElementTree 模块:
import xml.etree.ElementTree as ET2) 读取将被修改的文件并获取根节点,此处使用前文生成的 new.xml:
tree = ET.parse("new.xml") root = tree.getroot()3) 创建新节点 sub_new,添加属性和数据,并将其设置为 root 的子节点:
sub_new = ET.Element("sub_new") sub_new.attrib = {"name":"messi","age":"30"} sub_new.text = "new element" root.append(sub_new)4) 修改 sub1 的 attribute 属性:
sub1 = root.find("sub1") sub1.set("attribute","new attribute")5) 修改 sub2 的数据:
sub2 = root.find("sub2") sub2.text = "new value"6) 删除子节点 sub3:
sub3 = root.find("sub3") sub3.remove(sub3)7) 将修改结果写回原文件:
tree.write("new.xml")
流程的完整代码为:
import xml.etree.ElementTree as ET tree = ET.parse("new.xml") root = tree.getroot() sub_new = ET.Element("sub_new") sub_new.attrib = {"name":"messi","age":"30"} sub_new.text = "new element" root.append(sub_new) sub1 = root.find("sub1") sub1.set("attribute","new attribute") sub2 = root.find("sub2") sub2.text = "new value" sub3 = root.find("sub3") sub3.remove(sub3) tree.write("new.xml")运行后,new.xml 文件的内容将被修改为:
<root> <sub1 attribute="new attribute" /> <sub2>new value</sub2> <sub_new age="30" name="messi">new element</sub_new> </root>将 new.xml 调整一下格式后,更加直观,即:
<root> <sub1 attribute="new attribute" /> <sub2>new value</sub2> <sub_new age="30" name="messi">new element</sub_new> </root>可以看出,程序运行结果与预期一致:节点 sub1 的属性被修改,节点 sub2 的数据被修改,新增了子节点 sub_new,原来的节点 sub3 被删除。