XML(Extensible Markup Language)即可扩展标记语言,它可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。从结构上,它很像我们常见的HTML超文本标记语言。但他们被设计的目的是不同的,超文本标记语言被设计用来显示数据,其焦点是数据的外观。它被设计用来传输和存储数据,其焦点是数据的内容。
特点
- 由自定义标签对组成,<aa></aa>
- 标签可以有属性:<aa id='123'></aa>
- 标签对可以嵌入数据:<aa>abc</aa>
- 标签可以嵌入子标签(具有层级关系)
结构
xml文件可以理解为一个树结构,有根结点,子结点的概念。每个结点元素(包含结点名、属性和数据。
常见的 XML 编程接口有 DOM 和 SAX,这两种接口处理 XML 文件的方式不同,当然使用场合也不同。python 有三种方法解析 XML:
- SAX:https://docs.python.org/3.7/library/xml.sax.html
- DOM:https://docs.python.org/3.7/library/xml.dom.minidom.html
- ElementTree:https://docs.python.org/3.7/library/xml.etree.elementtree.html
python 使用 SAX 解析 xml
SAX 是一种基于事件驱动的 API。
利用 SAX 解析 XML 文档牵涉到两个部分: 解析器和事件处理器。
解析器负责读取 XML 文档, 并向事件处理器发送事件, 如元素开始跟元素结束事件;
而事件处理器则负责对事件作出相应, 对传递的 XML 数据进行处理。
1、对大型文件进行处理;
2、只需要文件的部分内容,或者只需从文件中得到特定信息。
3、想建立自己的对象模型的时候。
在 python 中使用 sax 方式处理 xml 要先引入 xml.sax 中的 parse 函数,还有 xml.sax.handler 中的 ContentHandler。
参考
https://docs.python.org/3.7/library/xml.sax.html
python使用 xml.dom 解析 xml
文件对象模型(Document Object Model,简称 DOM),是 W3C 组织推荐的处理可扩展置标语言的标准编程接口。
一个 DOM 的解析器在解析一个 XML 文档时,一次性读取整个文档,把文档中所有元素保存在内存中的一个树结构里,之后你可以利用 DOM 提供的不同的函数来读取或修改文档的内容和结构,也可以把修改过的内容写入 xml 文件。python 中用x ml.dom.minidom 来解析 xml 文件,实例如下:
参考
https://docs.python.org/3.7/library/xml.dom.minidom.html?highlight=xml%20dom#module-xml.dom.minidom
XML示例
<?xml version="1.0" encoding="utf-8"?>
<postgresql>
<connection>
<pg_host>localhost</pg_host>
<pg_port>5432</pg_port>
</connection>
</postgresql>
对应python示例
对xml文件中标签的值进行读取、修改、写入
import xml.dom.minidom #mxl.dom.minidom 模块被用来处理xml文件,所以要先引入
import os
def Change_param(filepath):
#打开xml文档
dom = xml.dom.minidom.parse(filepath) #ml.dom.minidom.parse() 用于打开一个xml文件,并将这个文件对象dom变量。
root = dom.documentElement #documentElement 用于得到dom对象的文档元素,并把获得的对象给root
#每一个结点都有它的nodeName,nodeValue,nodeType属性。
print (root.nodeName) # nodeName为结点名字
#获得root的子标签以的标签,对于知道名字的子标签,可以使用getElementsByTagName方法获取
#getElementsByTagName('tablist') 获取的是一个相同名称的标签列表,tablist[0]表示表示第一个
connection = root.getElementsByTagName('connection')
Hostlist = connection[0].getElementsByTagName('pg_host')
Portlist = connection[0].getElementsByTagName('pg_port')
posthost = Hostlist[0]
postport =Portlist[0]
print(posthost.firstChild.data)#改变前
print(postport.firstChild.data)
posthost.firstChild.data = "1.0.0.127" # .data是结点的值
postport.firstChild.data = "8080"
print(posthost.firstChild.data)#改变后
print(postport.firstChild.data)
#存储结果
with open('test.xml',"w") as f:
dom.writexml(f)
if __name__ == '__main__':
filepath="test.xml"
Change_param(filepath)
运行结果
python使用 ElementTree解析 xml
python中用于解析xml文件的模块很多,相比于xml.dom,xml.sax等,ET模块提供了一个轻量级、Pythonic的API.简而言之,更快,更便捷,而且也够用。
参考
https://docs.python.org/3.7/library/xml.etree.elementtree.html
- ElementTree.write("xmlfile"):更新xml文件
- Element.append():为当前element对象添加子元素(element)
- Element.set(key,value):为当前element的key属性设置value值
- Element.remove(element):删除为element的节点
import xml.etree.ElementTree as ET
#创建根节点
root = ET.Element("postgresql")
#创建子节点,并添加属性
connection = ET.SubElement(root,"connection")
connection.attrib = {"key":"value"}
#创建子节点,并添加数据
pg_host = ET.SubElement(connection,"pg_host")
pg_host.text = "1.0.0.127"
pg_port = ET.SubElement(connection,"pg_port")
pg_port.text = "8080"
#创建结点,并添加入父节点中
book2 = ET.Element("book")
title2 = ET.SubElement(book2,"title")
title2.attrib = {"lang":"en"}
title2.text = "Harry Potter"
root.append(book2)
#创建elementtree对象,写文件
tree = ET.ElementTree(root)
tree.write("test2.xml")
#读取待修改文件
updateTree = ET.parse("test.xml")
root = updateTree.getroot()
#修改属性
connection = root.find("connection")
connection.set("key","new_value")
#修改title的数据值
phost = connection.find("pg_host")
print(phost.text)
phost.text = "Newhost"
print(phost.text)
#删除子结点
for book in root.findall("book"):
if book.find("title").text == "Harry Potter":
root.remove("book")
#写回原文件
updateTree.write("test2.xml")