Python根据指定文件生成XML的方法

2020-10-08 0 635

    因项目需要根据指定格式的文件生成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, xmin, ymax, 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的资料请关注自学编程网其它相关文章!

遇见资源网 Python Python根据指定文件生成XML的方法 http://www.ox520.com/26275.html

常见问题

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务