python解析XML
首先我是用的是dom去解析我们xml文件。
一、读取XML文件
DOM 方式:DOM 中文译为文档对象模型,是 W3C 组织推荐的标准编程接口,它将 XML 数据在内存中解析成一个树,通过对树的操作来操作 XML
首先我们的一个xml的文本是:
<?xml version="1.0" encoding="utf-8"?>
<catalog>
<login username="pytest" passwd="123456">
<caption>Python</caption>
<item id="4">
<caption>测试</caption>
</item>
</login>
</catalog>
python代码:注意 xml.dom.minidom 模块是python自带的模块,不需要自行下载,直接用就行了
from xml.dom.minidom import xml
# 读取文件
dom = xml.dom.minidom.parse('test.xml')
# 获取XML文档对象
rootdata = dom.documentElement
# 获取标签之间的数据
itemlist = rootdata.getElementsByTagName('caption')
# 获取标签属性值 我们 caption
caption = itemlist[0].firstChild.data
print(caption)
结果是:
那么如果我们取值列表里面的是【1】是:
caption = itemlist[1].firstChild.data
print(caption)
结果是:
我们要是想读取:“<login username="pytest" passwd="123456">”
的数据:那么即是:
# 读取文件
dom = xml.dom.minidom.parse('test.xml')
# 获取XML文档对象
rootdata = dom.documentElement
# 获取标签之间的数据
itemlist = rootdata.getElementsByTagName('login')
# 获取标签属性值
login = itemlist [0].getAttribute('username')
pwd = itemlist [0].getAttribute('passwd')
print(login, pwd)
结果是:
如果我想遍历caption下面的数据:
# 读取文件
dom = xml.dom.minidom.parse('test.xml')
# 获取XML文档对象
rootdata = dom.documentElement
# 获取标签之间的数据
itemlist = rootdata.getElementsByTagName('caption')
# 遍历标签 caption 的数据
for i in range(len(itemlist)):
print("itemlist[i]:", type(itemlist[i]))
print(itemlist[i].firstChild.data)
结果是:
二、在python中写xml,生成xml文件
from xml.dom import minidom
# 1.创建DOM树对象
dom = minidom.Document()
# 2.创建根节点。每次都要用DOM对象来创建任何节点。
root_node = dom.createElement('root')
# 3.用DOM对象添加根节点
dom.appendChild(root_node)
# 用DOM对象创建元素子节点
book_node = dom.createElement('book')
# 用父节点对象添加元素子节点
root_node.appendChild(book_node)
# 设置该节点的属性
book_node.setAttribute('price', '199')
name_node = dom.createElement('name')
# 也用DOM创建文本节点,把文本节点(文字内容)看成子节点
name_text = dom.createTextNode('计算机程序设计语言 第1版')
# 用添加了文本的节点对象(看成文本节点的父节点)添加文本节点
name_node.appendChild(name_text)
# 每一个结点对象(包括dom对象本身)都有输出XML内容的方法,如:toxml()--字符串, toprettyxml()--美化树形格式。
try:
with open('dom_write.xml', 'w', encoding='UTF-8') as fh:
# 4.writexml()第一个参数是目标文件对象,第二个参数是根节点的缩进格式,第三个参数是其他子节点的缩进格式,
# 第四个参数制定了换行格式,第五个参数制定了xml内容的编码。
dom.writexml(fh, indent='', addindent='\t', newl='\n', encoding='UTF-8')
print('OK')
except Exception as err:
print('错误:{err}'.format(err=err))
三、1.在python中更新XML文件
参考:这个博客
思路分析:这个就是需要修改的customer.xml文件,主要是修改 <customer ID="C001">
下面的<phone>12345</phone>
的内容
<?xml version="1.0" encoding="utf-8"?><!-- This is list of customers -->
<customers>
<customer ID="C001">
<name>Acme Inc.</name>
<phone>12345</phone>
<comments>
<![CDATA[Regular customer since 1995]]>
</comments>
</customer>
<customer ID="C002">
<name>Star Wars Inc.</name>
<phone>23456</phone>
<comments>
<![CDATA[A small but healthy company.]]>
</comments>
</customer>
</customers>
修改代码如下:
from xml.dom.minidom import parse
class UpdateXml:
def update(self):
domTree = parse("customer.xml") # 定位xml文件
rootNode = domTree.documentElement # 获取XML文档对象
names = rootNode.getElementsByTagName("name") # 获取标签之间的数据 定位 <name>Acme Inc.</name>
# 如果定位 <customer ID="C001"> 标签属性值 用 names = rootNode.getAttribute('name')
for name in names:
if name.childNodes[0].data == "Acme Inc.":
# 获取到name节点的父节点
pn = name.parentNode
# 父节点的phone节点,其实也就是name的兄弟节点
phone = pn.getElementsByTagName("phone")[0]
# 更新phone的取值
phone.childNodes[0].data = 99999
with open('customer.xml', 'w+') as f:
# 缩进 - 换行 - 编码
domTree.writexml(f, addindent=' '+'\n', encoding='utf-8')
if __name__ == '__main__':
UpdateXml().update()
结果是:
我自己定义的代码所有改变,是根据查出来的标签之间的数据仅有一个的00 57 11 * * ? *
定时时间
修改xml内容是:
代码如下:
from xml.dom.minidom import parse
from jianlian.timeclass.class_time import DateTime
class UpdateXml:
@staticmethod
def jobstep3(url):
domtree = parse(url)
rootnode = domtree.documentElement
names = rootnode.getElementsByTagName("value")
data = []
for i in range(len(names)):
data.append(i)
test_data = data[1] # xml 前面还有一个 value 所以取 第二个
res = names[test_data].firstChild.data # 读取 value 的值 00 57 11 * * ? *
for name in names:
if name.childNodes[0].data == res:
pn = name.parentNode # 获取到 value 节点
phone = pn.getElementsByTagName("value")[0]
data = DateTime().random_minutes(3) + ' * * ? *' # DateTime这个是自己写的修改分钟的函数,可以参考我的<在python显示当前时间>文章中的random_minutes方法,在电脑时间的上,+3分钟
phone.childNodes[0].data = data # 更新 value 的值
with open(url, 'w+', encoding='utf-8') as f:
# 缩进 - 换行 - 编码
domtree.writexml(f, addindent='') # 我用的编码格式 GBK, 这个根据自己的实际情况来,这步是更新我们的xml文件。
if __name__ == '__main__':
url = r"xxxxxxx\xxxx\xxxx\xxxx\xxxx.xml"
UpdateXml.jobstep3(url)
结果如下:
2.在python中更新XML文件修改定时文件名称
1、替换单个文件配置路径:
修改文件的内容是:
<param-value>/WEB-INF/applicationContext*.xml,/WEB-INF/JobStep3.xml,/WEB-INF/D1Step2Job.xml,/WEB-INF/tblSettLimitJob.xml,/WEB-INF/ExcepMerWarnJob.xml,/WEB-INF/TranDetailJob.xml,/WEB-INF/AcsDataMigrationJob.xml
</param-value>
from xml.dom.minidom import parse
class UpdateXml:
@staticmethod
def replace_xml(url, values): # 'values = '/WEB-INF/JobStep3.xml'
"""替换单个文件配置"""
domtree = parse(url)
# 文档根元素
rootnode = domtree.documentElement
names = rootnode.getElementsByTagName("param-value")
data = []
for i in range(len(names)):
data.append(i)
test_data = data[0]
res = names[test_data].firstChild.data
# values = '/WEB-INF/JobStep3.xml'
for name in names:
if name.childNodes[0].data == res:
pn = name.parentNode
phone = pn.getElementsByTagName("param-value")[0]
if res.find(values) != -1: # xml文件存在 values 的定时 =-1 是不存在
print('已经存在{}定时,无需替换'.format(values))
else:
code = res.replace(res.split(',')[1], data)#替换为/WEB-INF/JobStep3.xml
phone.childNodes[0].data = code
print('定时更新为:{}'.format(code))
with open(url, 'w+', encoding='utf-8') as f:
# 缩进 - 换行 - 编码
domtree.writexml(f, addindent='')
if __name__ == '__main__':
file = r'D:\apache-tomcat-7.0.68-8080-11\webapps\PosMerchant\WEB-INF\web.xml'
values = '/WEB-INF/JobStep3.xml'
UpdateXml.replace_xml(file, values)
2、修改多个文件配置路径
from xml.dom.minidom import parse
def T1D1(url):
"""替换文件配置"""
domtree = parse(url)
# 文档根元素
rootnode = domtree.documentElement
names = rootnode.getElementsByTagName("param-value")
data = []
for i in range(len(names)):
data.append(i)
test_data = data[0]
res = names[test_data].firstChild.data
values = {'job3': '/WEB-INF/JobStep3.xml', 'd1': '/WEB-INF/D1Step2Job.xml'}
for name in names:
if name.childNodes[0].data == res:
pn = name.parentNode
phone = pn.getElementsByTagName("param-value")[0]
if res.find(values['job3']) != -1 and res.find(values['d1']) != -1: # xml文件存在 values 的定时 =-1 是不存在
print('web文件已经存在JobStep3和D1Step2Job的定时,无需替换')
else:
T1 = res.replace(res.split(',')[1], values['job3'])
print('修改web文件JobStep3的定时成功')
d1 = T1.replace(T1.split(',')[2], values['d1'])
print('修改web文件D1Step2Job的定时成功')
phone.childNodes[0].data = d1
print('定时更新为:{}'.format(d1))
with open(url, 'w+', encoding='utf-8') as f:
# 缩进 - 换行 - 编码
domtree.writexml(f, addindent='')
if __name__ == '__main__':
"""查询 web.xml 中的配置文件名称"""
file = r'D:\apache-tomcat-7.0.68-8080-11\webapps\PosMerchant\WEB-INF\web.xml'
T1D1(file)