Python根據指定檔案生成XML的方法
阿新 • • 發佈:2020-06-29
因專案需要根據指定格式的檔案生成XML標註檔案,可以方便使用LabelImg開啟進行編輯和檢視。其原始檔案預設使用逗號進行分隔,如下所示:
- 第1個值:原始圖片中切圖小檔案,以AIpng_x,其中x代表原始圖片的第幾個切圖檔案
- 第2~5值:分別對應於ymin,xmin,ymax,xmax
- 第6個值:代表對應的標籤標註
在生成XML檔案時,需要對其進行彙總,即將屬於同一個原始檔案的切圖小檔案的標註彙總到一起,其實現程式碼如下所示:
import os from Logger import MyLogger from xml.dom.minidom import Document from collections import defaultdict import re class OpeateXML: def __init__(self,srcPath: str,targetPath: str,srcFileName: str): self._srcPath = srcPath self._targetPath = targetPath self._srcFileName = srcFileName def readSrcFileName(self,fileEncoding="utf8") -> dict: data = defaultdict(list) s = re.compile("\.AIpng_\d{1,}",re.IGNORECASE) srcFileFullPath = os.path.join(self._srcPath,self._srcFileName) try: with open(srcFileFullPath,mode="r",encoding=fileEncoding,errors="ignore") as fr: for content in fr.readlines(): data[s.sub(".AIpng",content.strip().split(",")[0])].append(content.strip()) except Exception as ex: MyLogger().error(f"OperateXML:read file error:\n{ex}") return {} else: # data.sort(key=lambda x: x.strip().split(",")[0]) return data def createXML(self,data: dict,fileEncoding="utf8"): if data: try: for k,v in data.items(): doc = Document() # 建立根節點 rootNode = doc.createElement("annotation") # 新增根節點 doc.appendChild(rootNode) folder = doc.createElement("folder") folderText = doc.createTextNode(self._targetPath) folder.appendChild(folderText) rootNode.appendChild(folder) filename = doc.createElement("filename") filenameText = doc.createTextNode(k) filename.appendChild(filenameText) rootNode.appendChild(filename) path = doc.createElement("path") pathText = doc.createTextNode(os.path.join(self._targetPath,k)) path.appendChild(pathText) rootNode.appendChild(path) for i in v: tmpData = i.strip().split(",") if len(tmpData) == 6: _,ymin,xmax,labelName = tmpData objectObj = doc.createElement("object") rootNode.appendChild(objectObj) objectName = doc.createElement("name") objectNameText = doc.createTextNode(labelName) objectName.appendChild(objectNameText) objectObj.appendChild(objectName) objectBndBox = doc.createElement("bndbox") objectObj.appendChild(objectBndBox) objectBndBoxXmin = doc.createElement("xmin") objectBndBoxYmin = doc.createElement("ymin") objectBndBoxXmax = doc.createElement("xmax") objectBndBoxYmax = doc.createElement("ymax") objectBndBoxXminText = doc.createTextNode(xmin) objectBndBoxYminText = doc.createTextNode(ymin) objectBndBoxXmaxText = doc.createTextNode(xmax) objectBndBoxYmaxText = doc.createTextNode(ymax) objectBndBox.appendChild(objectBndBoxXmin) objectBndBox.appendChild(objectBndBoxYmin) objectBndBox.appendChild(objectBndBoxXmax) objectBndBox.appendChild(objectBndBoxYmax) objectBndBoxXmin.appendChild(objectBndBoxXminText) objectBndBoxYmin.appendChild(objectBndBoxYminText) objectBndBoxXmax.appendChild(objectBndBoxXmaxText) objectBndBoxYmax.appendChild(objectBndBoxYmaxText) objectObj.appendChild(objectBndBox) else: continue # save xml xmlName=os.path.splitext(k)[0]+".xml" targetPath = os.path.join(self._targetPath,xmlName) with open(targetPath,mode="w",encoding=fileEncoding) as fw: doc.writexml(fw,indent="\t",newl="\n",addindent="\t",encoding=fileEncoding) except Exception as ex: MyLogger().error(f"OperateXML:Save xml error\n{ex}") return if __name__ == '__main__': srcPath = r"C:\Users\Surpass\Documents\PycharmProjects\data\TEST-8\outs" srcName = "locations.txt" targetPath = r"C:\Users\Surpass\Documents\PycharmProjects\data\TEST-8\outs\in_number" operateXML = OpeateXML(srcPath,targetPath,srcName) a = operateXML.readSrcFileName() operateXML.createXML(a)
最終生成的XML效果如下所示:
在LabelImg中的效果如下所示:
PS:這裡再為大家提供幾款關於xml操作的線上工具供大家參考使用:
線上XML/JSON互相轉換工具:
http://tools.jb51.net/code/xmljson
線上格式化XML/線上壓縮XML:
http://tools.jb51.net/code/xmlformat
XML線上壓縮/格式化工具:
http://tools.jb51.net/code/xml_format_compress
XML程式碼線上格式化美化工具:
http://tools.jb51.net/code/xmlcodeformat
對關於Python生成XML相關內容感興趣的讀者可檢視本站專題:《Python操作xml資料技巧總結》
以上就是Python根據指定檔案生成XML的方法的詳細內容,更多關於Python生成XML的資料請關注我們其它相關文章!