1. 程式人生 > >批量修改xml檔案節點資訊

批量修改xml檔案節點資訊

今天來說說xml那些事兒.如何批量修改指定資料夾下的xml檔案的指定屬性.分三步走,首先,我們先看看如何讀寫單個

的xml檔案;第二步,來看看如何遍歷指定資料夾下的所有檔案,獲取到所有檔案的檔名;第三步,我們來看看一二之間

該如何銜接.好,lets do it

step1:對單個xml檔案進行讀寫

給定一個xml檔案:


  
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <catalog
    >
  3. <maxid>4 </maxid>
  4. <login username="pytest" passwd='123456'>
  5.    <caption>Python </caption
    >
  6. <item id="4">
  7. <caption>測試 </caption>
  8. </item>
  9. </login
    >
  10. <item id="2">
  11. <caption>Zope </caption>
  12. </item>
  13. </catalog>
來看看程式碼,怎麼讀取裡面的屬性(大家先照著註釋理解一遍,有空我再來詳細說明)


  
  1. #coding=utf-8
  2. import xml.dom.minidom
  3. #開啟xml文件
  4. dom=xml.dom.minidom.parse( 'test.xml')
  5. #得到文件元素物件
  6. root=dom.documentElement
  7. print root.nodeName
  8. print root.nodeValue
  9. print root.nodeType
  10. print root.ELEMENT_NODE
  11. #1.獲取maxid 這一node名字(沒有屬性值),如何獲取裡面的文字?
  12. bb=root.getElementsByTagName( 'maxid')
  13. b=bb[ 0]
  14. print b.nodeName
  15. #2.獲取login 這一node名字及相關屬性值
  16. login=root.getElementsByTagName( 'login')
  17. login=login[ 0] #獲取login的相關屬性值
  18. un=login.getAttribute( "username")
  19. print un
  20. pd=login.getAttribute( "passwd")
  21. print pd
  22. #修改先關屬性值
  23. #3.獲取節點名為item的相關屬性值
  24. item=root.getElementsByTagName( 'item') #獲取了所有名字為item的node
  25. item=item[ 0] #拿到第一個item,獲取相關屬性值
  26. i=item.getAttribute( "id") #獲取id的值
  27. print i
  28. #4.獲取標籤對之間的資料,並修改為新的值
  29. caption=root.getElementsByTagName( 'caption')
  30. c0=caption[ 0]
  31. print c0.firstChild.data #firstChild屬性返回被選節點的第一個子節點,.data表示獲取該節點資料
  32. c1=caption[ 1]
  33. print c1.firstChild.data
  34. c2=caption[ 2] #caption節點有三個!!!
  35. print c2.firstChild.data
  36. #修改標籤對之間的資料,直接對節點資料賦值
  37. c2.firstChild.data= 'dhhdlh'
  38. print c2.firstChild.data
好了,看完了demo,我們現在來實戰操練一番,使用通用的VOC2007標註資料集,xml檔案長這個樣子:


  
  1. <annotation verified="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>
那麼,我們該如何修改呢?請看:


  
  1. #coding=utf-8
  2. import xml.dom.minidom
  3. ###批量讀取xml檔案
  4. ###讀取單個xml檔案
  5. dom=xml.dom.minidom.parse( '000002.xml')
  6. root=dom.documentElement
  7. #獲取標籤對name/pose之間的值
  8. name=root.getElementsByTagName( 'name')
  9. pose=root.getElementsByTagName( 'pose')
  10. #原始資訊
  11. print '原始資訊'
  12. n0=name[ 0]
  13. print n0.firstChild.data
  14. n1=name[ 1]
  15. print n1.firstChild.data
  16. p0=pose[ 0]
  17. print p0.firstChild.data
  18. p1=pose[ 1]
  19. print p1.firstChild.data
  20. #修改標籤對之間的值
  21. n0.firstChild.data= 'circle'
  22. n1.firstChild.data= 'circle'
  23. p0.firstChild.data= 'ok'
  24. p1.firstChild.data= 'ok'
  25. #列印輸出
  26. print '修改後的 name'
  27. print n0.firstChild.data
  28. print n1.firstChild.data
  29. print '修改後的 pose'
  30. print p0.firstChild.data
  31. print p1.firstChild.data
好了,現在我們學會了如何對單個檔案進行修改,那麼多個檔案呢?

step2:遍歷指定路徑下的檔案:


  
  1. #coding=utf-8
  2. import os
  3. import os.path
  4. import xml.dom.minidom
  5. path= "/home/nvidia/xmlReader/xml/"
  6. files=os.listdir(path) #得到資料夾下所有檔名稱
  7. s=[]
  8. for xmlFile in files: #遍歷資料夾
  9. if not os.path.isdir(xmlFile): #判斷是否是資料夾,不是資料夾才打開
  10. print xmlFile
(path下我放的是幾個xml檔案),列印xmlFile我們發現是這樣的:


看到沒,看到這個的話就說明我們已經成功一半了!!!接下來我們把之前寫的讀取單個xml檔案的程式碼放進去


  
  1. #coding=utf-8
  2. import os
  3. import os.path
  4. import xml.dom.minidom
  5. path= "/home/nvidia/xmlReader/xml/"
  6. files=os.listdir(path) #得到資料夾下所有檔名稱
  7. s=[]
  8. for xmlFile in files: #遍歷資料夾
  9. if not os.path.isdir(xmlFile): #判斷是否是資料夾,不是資料夾才打開
  10. print xmlFile
  11. #TODO
  12. #xml檔案讀取操作
  13. #將獲取的xml檔名送入到dom解析
  14. dom=xml.dom.minidom.parse(xmlFile)
  15. root=dom.documentElement
  16. #獲取標籤對name/pose之間的值
  17. name=root.getElementsByTagName( 'name')
  18. pose=root.getElementsByTagName( 'pose')
  19. #原始資訊
  20. print '原始資訊'
  21. n0=name[ 0]
  22. print n0.firstChild.data
  23. n1=name[ 1]
  24. print n1.firstChild.data
  25. p0=pose[ 0]
  26. print p0.firstChild.data
  27. p1=pose[ 1]
  28. print p1.firstChild.data
直接執行,報錯!!我...

不要急,我們一點點來解決,,遇到問題是很正常的嘛!!!首先我們看看遇到什麼錯?


列印除了000001.xml但是在實際讀取的時候出錯了!!還說找不到在這個檔案?why??仔細想想發現,這裡可能要傳入的是

每個xml檔案的具體路徑,有了這個想法之後我們再來看看:

這個時候就設涉及到Python路徑拼接的知識了:


  
  1. path= "/home/nvidia/xmlReader/xml/"
  2. xmlFile也是幾個字串
  3. os.path.join(path,xmlFile)
  4. #os.path.join("/home/test","test.xml")

那麼,我們就拼接好了.然後就執行看看:



啊哈?!居然對了!!哈哈哈,大功告成!接下來就是先將影象分好類,然後就可以批量修改檔案了


好了,讓我們開看看最終的程式碼:


  
  1. #coding=utf-8
  2. import os
  3. import os.path
  4. import xml.dom.minidom
  5. path= "/home/nvidia/xmlReader/xml/"
  6. files=os.listdir(path) #得到資料夾下所有檔名稱
  7. s=[]
  8. for xmlFile in files: #遍歷資料夾
  9. if not os.path.isdir(xmlFile): #判斷是否是資料夾,不是資料夾才打開
  10. print xmlFile
  11. #TODO
  12. #xml檔案讀取操作
  13. #將獲取的xml檔名送入到dom解析
  14. dom=xml.dom.minidom.parse(os.path.join(path,xmlFile)) ###最核心的部分,路徑拼接,輸入的是具體路徑
  15. root=dom.documentElement
  16. #獲取標籤對name/pose之間的值
  17. name=root.getElementsByTagName( 'name')
  18. pose=root.getElementsByTagName( 'pose')
  19. #原始資訊
  20. print '原始資訊'
  21. n0=name[ 0]
  22. print n0.firstChild.data
  23. p0=pose[ 0]
  24. print p0.firstChild.data
  25. #修改
  26. n0.firstChild.data= 'circle'
  27. p0.firstChild.data= 'ok'
  28. #列印輸出
  29. print '修改後的 name'
  30. print n0.firstChild.data