python批量修改xml属性

匿名 (未验证) 提交于 2019-12-02 22:54:36

今天来说说xml那些事儿.如何批量修改指定文件夹下的xml文件的指定属性.分三步走,首先,我们先看看如何读写单个

的xml文件;第二步,来看看如何遍历指定文件夹下的所有文件,获取到所有文件的文件名;第三步,我们来看看一二之间

该如何衔接.好,lets do it

step1:对单个xml文件进行读写

给定一个xml文件:

  1. <?xmlversion=“1.0”encoding=“utf-8”?>
  2. <catalog>
  3. <maxid>4</maxid>
  4. <loginusername=“pytest”passwd=‘123456’>
  5. <caption>Python</caption>
  6. <itemid=“4”>
  7. <caption>测试</caption>
  8. </item>
  9. </login>
  10. <itemid=“2”>
  11. <caption>Zope</caption>
  12. </item>
  13. </catalog>
<?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>
来看看代码,怎么读取里面的属性(大家先照着注释理解一遍,有空我再来详细说明)

  1. #coding=utf-8
  2. import
  3. #打开xml文档
  4. dom=xml.dom.minidom.parse(’test.xml’
  5. #得到文档元素对象
  6. print
  7. print
  8. print
  9. print
  10. bb=root.getElementsByTagName(’maxid’
  11. b=bb[0
  12. print
  13. login=root.getElementsByTagName(’login’
  14. login=login[0#获取login的相关属性值
  15. un=login.getAttribute(”username”
  16. print
  17. pd=login.getAttribute(”passwd”
  18. print
  19. #修改先关属性值
  20. #3.获取节点名为item的相关属性值
  21. item=root.getElementsByTagName(’item’#获取了所有名字为item的node
  22. item=item[0#拿到第一个item,获取相关属性值
  23. i=item.getAttribute(”id”)#获取id的值
  24. print
  25. #4.获取标签对之间的数据,并修改为新的值
  26. caption=root.getElementsByTagName(’caption’
  27. c0=caption[0
  28. print#firstChild属性返回被选节点的第一个子节点,.data表示获取该节点数据
  29. c1=caption[1
  30. print
  31. c2=caption[2#caption节点有三个!!!
  32. print
  33. #修改标签对之间的数据,直接对节点数据赋值
  34. c2.firstChild.data=’dhhdlh’
  35. print
#coding=utf-8 import xml.dom.minidom      

dom=xml.dom.minidom.parse('test.xml')

root=dom.documentElement
print root.nodeName
print root.nodeValue
print root.nodeType
print root.ELEMENT_NODE

bb=root.getElementsByTagName('maxid')
b=bb[0]
print b.nodeName

login=root.getElementsByTagName('login')
login=login[0] #获取login的相关属性值
un=login.getAttribute("username")
print un
pd=login.getAttribute("passwd")
print pd

item=root.getElementsByTagName('item') #获取了所有名字为item的node
item=item[0] #拿到第一个item,获取相关属性值
i=item.getAttribute("id")#获取id的值
print i

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文件长这个样子:

  1. <annotationverified=“no”>
  2. <folder>row_img</folder>
  3. <filename>000002</filename>
  4. <path>/home/nvidia/labelImg-master/img_change/row_img/000002.jpg</path>
  5. <source>
  6. <database>Unknown</database>
  7. </source>
  8. <size>
  9. <width>1200</width>
  10. <height>800</height>
  11. <depth>3</depth>
  12. </size>
  13. <segmented>0</segmented>
  14. <object>
  15. <name>qwe</name>
  16. <pose>Unspecified</pose>
  17. <truncated>0</truncated>
  18. <difficult>0</difficult>
  19. <bndbox>
  20. <xmin>513</xmin>
  21. <ymin>265</ymin>
  22. <xmax>921</xmax>
  23. <ymax>663</ymax>
  24. </bndbox>
  25. </object>
  26. <object>
  27. <name>wieoiwpe</name>
  28. <pose>Unspecified</pose>
  29. <truncated>0</truncated>
  30. <difficult>0</difficult>
  31. <bndbox>
  32. <xmin>513</xmin>
  33. <ymin>265</ymin>
  34. <xmax>921</xmax>
  35. <ymax>663</ymax>
  36. </bndbox>
  37. </object>
  38. </annotation>
<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> 
那么,我们该如何修改呢?请看:

  1. #coding=utf-8
  2. import
  3. ###批量读取xml文件
  4. ###读取单个xml文件
  5. dom=xml.dom.minidom.parse(’000002.xml’
  6. #获取标签对name/pose之间的值
  7. name=root.getElementsByTagName(’name’
  8. pose=root.getElementsByTagName(’pose’
  9. #原始信息
  10. print‘原始信息’
  11. n0=name[0
  12. print
  13. n1=name[1
  14. print
  15. p0=pose[0
  16. print
  17. p1=pose[1
  18. print
  19. #修改标签对之间的值
  20. n0.firstChild.data=’circle’
  21. n1.firstChild.data=’circle’
  22. p0.firstChild.data=’ok’
  23. p1.firstChild.data=’ok’
  24. #打印输出
  25. print
  26. print
  27. print
  28. print
  29. print
  30. print
#coding=utf-8 import xml.dom.minidom      

dom=xml.dom.minidom.parse('000002.xml')

root=dom.documentElement

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:遍历指定路径下的文件:

  1. #coding=utf-8
  2. import
  3. import
  4. import
  5. path=”/home/nvidia/xmlReader/xml/”
  6. #得到文件夹下所有文件名称
  7. forin#遍历文件夹
  8. ifnot#判断是否是文件夹,不是文件夹才打开
  9. print
#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文件的代码放进去

  1. #coding=utf-8
  2. import
  3. import
  4. import
  5. path=”/home/nvidia/xmlReader/xml/”
  6. #得到文件夹下所有文件名称
  7. forin#遍历文件夹
  8. ifnot#判断是否是文件夹,不是文件夹才打开
  9. print
  10. #TODO
  11. #xml文件读取操作
  12. #将获取的xml文件名送入到dom解析
  13. #获取标签对name/pose之间的值
  14. ’name’
  15. ’pose’
  16. #原始信息
  17. print‘原始信息’
  18. 0
  19. print
  20. 1
  21. print
  22. 0
  23. print
  24. 1
  25. print
#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路径拼接的知识了:

  1. path=“/home/nvidia/xmlReader/xml/”
  2. #os.path.join(“/home/test”,”test.xml”)
path="/home/nvidia/xmlReader/xml/" xmlFile也是几个字符串 os.path.join(path,xmlFile)     

os.path.join("/home/test","test.xml")

那么,我们就拼接好了.然后就执行看看:



啊哈?!居然对了!!哈哈哈,大功告成!接下来就是先将图像分好类,然后就可以批量修改文件了


好了,让我们开看看最终的代码:

  1. #coding=utf-8
  2. import
  3. import
  4. import
  5. path=”/home/nvidia/xmlReader/xml/”
  6. #得到文件夹下所有文件名称
  7. forin#遍历文件夹
  8. ifnot#判断是否是文件夹,不是文件夹才打开
  9. print
  10. #TODO
  11. #xml文件读取操作
  12. #将获取的xml文件名送入到dom解析
  13. ###最核心的部分,路径拼接,输入的是具体路径
  14. #获取标签对name/pose之间的值
  15. ’name’
  16. ’pose’
  17. #原始信息
  18. print‘原始信息’
  19. 0
  20. print
  21. 0
  22. print
  23. #修改
  24. ’circle’
  25. ’ok’
  26. #打印输出
  27. print
  28. print
  29. print
  30. print
  31. print‘~~~~~’
#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更新*******************

这里要用到一个重要的关系:Python中的迭代(不同于c++/C,不能写成for i in len(object))而要写成

  1. forin
  2. print
for i in range(len(pose)):        print pose[i].firstChild.data

这样的话,即使我们不知道有几处要修改的地方,但是我们都能够找出来,修改掉(这里每个pose都修改成同样的属性)

修改后,还需要保存到xml文件,修改后的代码为:

  1. #coding=utf-8
  2. import
  3. import
  4. import
  5. path=”/home/nvidia/xmlReader/xml/”
  6. #得到文件夹下所有文件名称
  7. forin#遍历文件夹
  8. ifnot#判断是否是文件夹,不是文件夹才打开
  9. print
  10. #TODO
  11. #xml文件读取操作
  12. #将获取的xml文件名送入到dom解析
  13. ###最核心的部分os.path.join(path,xmlFile),路径拼接,输入的是具体路径
  14. #获取标签对name/pose之间的值
  15. ’name’
  16. ’pose’
  17. forin
  18. print
  19. ’circle’
  20. print
  21. forin
  22. print
  23. ’ok’
  24. print
  25. #保存修改到xml文件中
  26. ’w’
  27. print(
#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:

dom.writexml(fh,indent='',addindent='\t',newl='\n',encoding='UTF-8')

    </pre><br> 

参考博客:https://www.cnblogs.com/wcwnina/p/7222180.html




今天来说说xml那些事儿.如何批量修改指定文件夹下的xml文件的指定属性.分三步走,首先,我们先看看如何读写单个

的xml文件;第二步,来看看如何遍历指定文件夹下的所有文件,获取到所有文件的文件名;第三步,我们来看看一二之间

该如何衔接.好,lets do it

step1:对单个xml文件进行读写

给定一个xml文件:

  1. <?xmlversion=“1.0”encoding=“utf-8”?>
  2. <catalog>
  3. <maxid>4</maxid>
  4. <loginusername=“pytest”passwd=‘123456’>
  5. <caption>Python</caption>
  6. <itemid=“4”>
  7. <caption>测试</caption>
  8. </item>
  9. </login>
  10. <itemid=“2”>
  11. <caption>Zope</caption>
  12. </item>
  13. </catalog>
<?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>
来看看代码,怎么读取里面的属性(大家先照着注释理解一遍,有空我再来详细说明)

  1. #coding=utf-8
  2. import
  3. #打开xml文档
  4. dom=xml.dom.minidom.parse(’test.xml’
  5. #得到文档元素对象
  6. print
  7. print
  8. print
  9. print
  10. bb=root.getElementsByTagName(’maxid’
  11. b=bb[0
  12. print
  13. login=root.getElementsByTagName(’login’
  14. login=login[0#获取login的相关属性值
  15. un=login.getAttribute(”username”
  16. print
  17. pd=login.getAttribute(”passwd”
  18. print
  19. #修改先关属性值
  20. #3.获取节点名为item的相关属性值
  21. item=root.getElementsByTagName(’item’#获取了所有名字为item的node
  22. item=item[0#拿到第一个item,获取相关属性值
  23. i=item.getAttribute(”id”)#获取id的值
  24. print
  25. #4.获取标签对之间的数据,并修改为新的值
  26. caption=root.getElementsByTagName(’caption’
  27. c0=caption[0
  28. print#firstChild属性返回被选节点的第一个子节点,.data表示获取该节点数据
  29. c1=caption[1
  30. print
  31. c2=caption[2#caption节点有三个!!!
  32. print
  33. #修改标签对之间的数据,直接对节点数据赋值
  34. c2.firstChild.data=’dhhdlh’
  35. print
#coding=utf-8 import xml.dom.minidom      
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!