1. 程式人生 > 程式設計 >Python根據指定檔案生成XML的方法

Python根據指定檔案生成XML的方法

    因專案需要根據指定格式的檔案生成XML標註檔案,可以方便使用LabelImg開啟進行編輯和檢視。其原始檔案預設使用逗號進行分隔,如下所示:

Python根據指定檔案生成XML的方法

  • 第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效果如下所示:

Python根據指定檔案生成XML的方法

    在LabelImg中的效果如下所示:

Python根據指定檔案生成XML的方法

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的資料請關注我們其它相關文章!