使用python编辑XML文件

XML(Extensible Markup Language)即可扩展标记语言,它可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。从结构上,它很像我们常见的HTML超文本标记语言。但他们被设计的目的是不同的,超文本标记语言被设计用来显示数据,其焦点是数据的外观。它被设计用来传输存储数据,其焦点是数据的内容

特点
  • 自定义标签对组成,<aa></aa>
  • 标签可以有属性:<aa id='123'></aa>
  • 标签对可以嵌入数据:<aa>abc</aa>
  • 标签可以嵌入子标签(具有层级关系)
结构

xml文件可以理解为一个树结构,有根结点,子结点的概念。每个结点元素(包含结点名、属性和数据。


xml结构示意图

常见的 XML 编程接口有 DOM 和 SAX,这两种接口处理 XML 文件的方式不同,当然使用场合也不同。python 有三种方法解析 XML:


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")
运行结果
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,284评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,115评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,614评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,671评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,699评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,562评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,309评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,223评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,668评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,859评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,981评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,705评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,310评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,904评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,023评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,146评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,933评论 2 355

推荐阅读更多精彩内容