python批量修改xml属性的实现方式
作者:coding思想 发布时间:2022-10-03 12:34:58
今天来说说xml那些事儿.如何批量修改指定文件夹下的xml文件的指定属性.分三步走,首先,我们先看看如何读写单个
的xml文件;第二步,来看看如何遍历指定文件夹下的所有文件,获取到所有文件的文件名;第三步,我们来看看一二之间
该如何衔接.好,lets do it
step1:对单个xml文件进行读写
给定一个xml文件:
<?xml version="1.0" encoding="utf-8"?>
<catalog>
<maxid>4</maxid>
<login username="pytest" passwd='123456'>
<caption>Python</caption>
<item id="4">
<caption>测试</caption>
</item>
</login>
<item id="2">
<caption>Zope</caption>
</item>
</catalog>
来看看代码,怎么读取里面的属性(大家先照着注释理解一遍,有空我再来详细说明)
#coding=utf-8
import xml.dom.minidom
#打开xml文档
dom=xml.dom.minidom.parse('test.xml')
#得到文档元素对象
root=dom.documentElement
print root.nodeName
print root.nodeValue
print root.nodeType
print root.ELEMENT_NODE
#1.获取maxid 这一node名字(没有属性值),如何获取里面的文本?
bb=root.getElementsByTagName('maxid')
b=bb[0]
print b.nodeName
#2.获取login 这一node名字及相关属性值
login=root.getElementsByTagName('login')
login=login[0] #获取login的相关属性值
un=login.getAttribute("username")
print un
pd=login.getAttribute("passwd")
print pd
#修改先关属性值
#3.获取节点名为item的相关属性值
item=root.getElementsByTagName('item') #获取了所有名字为item的node
item=item[0] #拿到第一个item,获取相关属性值
i=item.getAttribute("id")#获取id的值
print i
#4.获取标签对之间的数据,并修改为新的值
caption=root.getElementsByTagName('caption')
c0=caption[0]
print c0.firstChild.data #firstChild属性返回被选节点的第一个子节点,.data表示获取该节点数据
c1=caption[1]
print c1.firstChild.data
c2=caption[2] #caption节点有三个!!!
print c2.firstChild.data
#修改标签对之间的数据,直接对节点数据赋值
c2.firstChild.data='dhhdlh'
print c2.firstChild.data
好了,看完了demo,我们现在来实战操练一番,使用通用的VOC2007标注数据集,xml文件长这个样子:
<annotation verified="no">
<folder>row_img</folder>
<filename>000002</filename>
<path>/home/nvidia/labelImg-master/img_change/row_img/000002.jpg</path>
<source>
<database>Unknown</database>
</source>
<size>
<width>1200</width>
<height>800</height>
<depth>3</depth>
</size>
<segmented>0</segmented>
<object>
<name>qwe</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>513</xmin>
<ymin>265</ymin>
<xmax>921</xmax>
<ymax>663</ymax>
</bndbox>
</object>
<object>
<name>wieoiwpe</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>513</xmin>
<ymin>265</ymin>
<xmax>921</xmax>
<ymax>663</ymax>
</bndbox>
</object>
</annotation>
那么,我们该如何修改呢?请看:
#coding=utf-8
import xml.dom.minidom
###批量读取xml文件
###读取单个xml文件
dom=xml.dom.minidom.parse('000002.xml')
root=dom.documentElement
#获取标签对name/pose之间的值
name=root.getElementsByTagName('name')
pose=root.getElementsByTagName('pose')
#原始信息
print '原始信息'
n0=name[0]
print n0.firstChild.data
n1=name[1]
print n1.firstChild.data
p0=pose[0]
print p0.firstChild.data
p1=pose[1]
print p1.firstChild.data
#修改标签对之间的值
n0.firstChild.data='circle'
n1.firstChild.data='circle'
p0.firstChild.data='ok'
p1.firstChild.data='ok'
#打印输出
print '修改后的 name'
print n0.firstChild.data
print n1.firstChild.data
print '修改后的 pose'
print p0.firstChild.data
print p1.firstChild.data
好了,现在我们学会了如何对单个文件进行修改,那么多个文件呢?
step2:遍历指定路径下的文件:
#coding=utf-8
import os
import os.path
import xml.dom.minidom
path="/home/nvidia/xmlReader/xml/"
files=os.listdir(path) #得到文件夹下所有文件名称
s=[]
for xmlFile in files: #遍历文件夹
if not os.path.isdir(xmlFile): #判断是否是文件夹,不是文件夹才打开
print xmlFile
(path下我放的是几个xml文件),打印xmlFile我们发现是这样的:
看到没,看到这个的话就说明我们已经成功一半了!!!接下来我们把之前写的读取单个xml文件的代码放进去
#coding=utf-8
import os
import os.path
import xml.dom.minidom
path="/home/nvidia/xmlReader/xml/"
files=os.listdir(path) #得到文件夹下所有文件名称
s=[]
for xmlFile in files: #遍历文件夹
if not os.path.isdir(xmlFile): #判断是否是文件夹,不是文件夹才打开
print xmlFile
#TODO
#xml文件读取操作
#将获取的xml文件名送入到dom解析
dom=xml.dom.minidom.parse(xmlFile)
root=dom.documentElement
#获取标签对name/pose之间的值
name=root.getElementsByTagName('name')
pose=root.getElementsByTagName('pose')
#原始信息
print '原始信息'
n0=name[0]
print n0.firstChild.data
n1=name[1]
print n1.firstChild.data
p0=pose[0]
print p0.firstChild.data
p1=pose[1]
print p1.firstChild.data
直接运行,报错!!我...
不要急,我们一点点来解决,,遇到问题是很正常的嘛!!!首先我们看看遇到什么错?
打印除了000001.xml但是在实际读取的时候出错了!!还说找不到在这个文件?why??仔细想想发现,这里可能要传入的是
每个xml文件的具体路径,有了这个想法之后我们再来看看:
这个时候就设涉及到Python路径拼接的知识了:
path="/home/nvidia/xmlReader/xml/"
xmlFile也是几个字符串
os.path.join(path,xmlFile)
#os.path.join("/home/test","test.xml")
那么,我们就拼接好了.然后就执行看看:
啊哈?!居然对了!!哈哈哈,大功告成!接下来就是先将图像分好类,然后就可以批量修改文件了
好了,让我们开看看最终的代码:
#coding=utf-8
import os
import os.path
import xml.dom.minidom
path="/home/nvidia/xmlReader/xml/"
files=os.listdir(path) #得到文件夹下所有文件名称
s=[]
for xmlFile in files: #遍历文件夹
if not os.path.isdir(xmlFile): #判断是否是文件夹,不是文件夹才打开
print xmlFile
#TODO
#xml文件读取操作
#将获取的xml文件名送入到dom解析
dom=xml.dom.minidom.parse(os.path.join(path,xmlFile)) ###最核心的部分,路径拼接,输入的是具体路径
root=dom.documentElement
#获取标签对name/pose之间的值
name=root.getElementsByTagName('name')
pose=root.getElementsByTagName('pose')
#原始信息
print '原始信息'
n0=name[0]
print n0.firstChild.data
p0=pose[0]
print p0.firstChild.data
#修改
n0.firstChild.data='circle'
p0.firstChild.data='ok'
#打印输出
print '修改后的 name'
print n0.firstChild.data
print '修改后的 pose'
print p0.firstChild.data
print '~~~~~'
其实,就我个人来讲,还有个需求,就是文件匹配:根据A文件夹中的文件名,在B文件夹匹配同名但不同格式的文件,然后将他们单独
拎出来,复制到C文件夹保存,具体该怎么做呢?下一篇博客即将揭晓,拭目以待.
******************2018.1.27更新*******************
上面说的方法基于我们已经知道了xml文件中有几个pose属性几个object属性,但是一般在修改之前我们是不知道的,那么如何自动的去识别并修改每个属性的值呢?接下来我们开看看
这里要用到一个重要的关系:Python中的迭代(不同于c++/C,不能写成for i in len(object))而要写成
for i in range(len(pose)):
print pose[i].firstChild.data
这样的话,即使我们不知道有几处要修改的地方,但是我们都能够找出来,修改掉(这里每个pose都修改成同样的属性)
修改后,还需要保存到xml文件,修改后的代码为:
#coding=utf-8
import os
import os.path
import xml.dom.minidom
path="/home/nvidia/xmlReader/xml/"
files=os.listdir(path) #得到文件夹下所有文件名称
s=[]
for xmlFile in files: #遍历文件夹
if not os.path.isdir(xmlFile): #判断是否是文件夹,不是文件夹才打开
print xmlFile
#TODO
#xml文件读取操作
#将获取的xml文件名送入到dom解析
dom=xml.dom.minidom.parse(os.path.join(path,xmlFile)) ###最核心的部分os.path.join(path,xmlFile),路径拼接,输入的是具体路径
root=dom.documentElement
#获取标签对name/pose之间的值
name=root.getElementsByTagName('name')
pose=root.getElementsByTagName('pose')
#重命名class name
for i in range(len(name)):
print name[i].firstChild.data
name[i].firstChild.data='circle'
print name[i].firstChild.data
for j in range(len(pose)):
print pose[j].firstChild.data
pose[j].firstChild.data='ok'
print pose[j].firstChild.data
#保存修改到xml文件中
with open(os.path.join(path,xmlFile),'w') as fh:
dom.writexml(fh)
print('写入name/pose OK!')
# 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('写入xml OK!')
来源:https://blog.csdn.net/LOVE1055259415/article/details/79166754


猜你喜欢
- 本文实例讲述了Python实现的批量修改文件后缀名操作。分享给大家供大家参考,具体如下:windows和linux下都支持该程序
- 代码如下:function checkip(checkstring)'用正则判断IP是否合法 dim re1 set re1=new
- 获取航线信息并且制作成图航线信息航线信息查询网站本次实例使用的航班号为 CES5496查询后在network中可以寻找到如下内容https:
- 本文实例讲述了python函数形参用法。分享给大家供大家参考。具体如下:函数形参:函数取得的参数是你提供给函数的值,这样函数就可以利用这些值
- 前言DISTINCT 实际上和 GROUP BY 操作的实现非常相似,只不过是在 GROUP BY 之后的每组中只取出一条记录而已。所以,D
- 这篇文章主要是用PHP函数实现数字与文字分页,具体实现步骤就不罗嗦了,直接上代码/** * * @param $_sql * @param
- 本文实例分析了Python多线程操作数据库相关问题。分享给大家供大家参考,具体如下:python多线程并发操作数据库,会存在链接数据库超时、
- 在网上查了部分资料但是发现粘上去的代码都存在问题,无奈只好自己修改了一下,代码如下: 如下代码能正常运行,都是网上查找资料最后拼凑总结出来的
- 在某些编程语言中,例如 C/C++、C#、PHP、Java、JavaScript 等等,do-while 是一种基本的循环结构。它的核心语义
- Ubuntu Server 16.04下mysql8.0安装配置图文教程1.从Mysql官网上下载安装文件。有两种方式可供选择:使用APT安
- 好久没有写ASP代码了,今天在做一个简单的留言本时,出现了一下错误:Microsoft Office Access Database Eng
- CONVERT的使用方法: 格式: CONVERT(data_type,expression[,style]) 说明: 此样式一般在时间类型
- 在图片中识别足球先补充下霍夫圆变换的几个参数知识:dp,用来检测圆心的累加器图像的分辨率于输入图像之比的倒数,且此参数允许创建一个比输入图像
- \\create by ahuinan 2009-6-22 \\up by ahuian 2009-6-23 \\up by ahuinan
- 本文为大家分享了python操作excel的包,供大家参考,具体内容如下现在支持python操作excel的包有下列这些官网上最推荐的是op
- 大家既然能看到这个视频,说明大家对跨域已经有了一定的理解,所以这里就不花功夫对跨域进行详细的介绍了1. 首先扩展一点,axios在本地发送的
- 画一个地球想画一个转动的地球,那么首先要有一个球,或者说要有一个球面,用参数方程可以表示为x=rcosϕcosθy=rc
- 最近开始实习,工作技术栈主要Python和Golang,目前的任务把Python模块重构为GO模块,然后出现了一个问题,就是要将一个结构体按
- 字体的处理在网页设计中无论怎么强调也不为过,毕竟网页使用来传递信息的,而最经典最直接的信息传递方式就是
- 步骤一:申请百度地图密钥;JavaScript API v1.4以及以前的版本无序申请秘钥(ak),自v1.5版本开始需要先申请秘钥(ak)