批量修改xml檔案節點資訊
阿新 • • 發佈:2018-11-03
今天來說說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
-