Python读写xml文件

  • xml文件知识点
  • 读取xml文件
  • 写入xml文件
  • VOC数据集类别提取
  • 最近需要提取VOC数据集中的特定类别,所以就学习一下xml文件的读取和写入,毕竟xml格式的标签在目标检测中还是用的比较多的

    参考博客:
    https://blog.csdn.net/hu694028833/article/details/81089959
    https://blog.csdn.net/wsp_1138886114/article/details/86576900

    xml文件知识点

    主要学习 基于ElementTree
    XML是可扩展标记语言(Extensible Markup Language)的缩写,其中标记是关键部分。用户可以创建内容,然后使用限定标记标记它,从而使每个单词、短语或块成为可识别、可分类的信息。
    常见的XML编程接口有DOM和SAX,这两种接口处理XML文件的方式不同,使用场合也不同。DOM是由W3C官方提出的标准,它会把整个XML文件读入内存,并将该文件解析成树,我们可以通过访问树的节点的方式访问XML中的标签,但是这种方法占用内存大,解析慢,如果读入文件过大,尽量避免使用这种方法。SAX是事件驱动的,通过在解析XML的过程中触发一个个的事件并调用用户自定义的回调函数来处理XML文件,速度比较快,占用内存少,但是需要用户实现回调函数,因此Python标准库的官方文档中这样介绍SAX:SAX每次只允许你查看文档的一小部分,你无法通过当前获取的元素访问其他元素。Python中提供了很多包支持XML文件的解析,如xml.dom,xml.sax,xml.dom.minidom和xml.etree.ElementTree等

    读取xml文件

    读取文档:tree = ET.parse(‘test.xml’)
    获得根节点:root = tree.getroot()
    获得所有子节点:list(root)
    查找子节点,注意这里不会递归查找所有子节点:root.findall(‘object’)
    查找子节点,递归查找所有子节点:root.iter(‘object’)
    查看节点名称:root.tag

    写入xml文件

    创建节点:root = ET.Element(‘Root’)
    创建文档:tree = ET.ElementTree(root)
    设置文本值:element.text = ‘default’
    设置属性:element.set(‘age’, str(i))
    添加节点:root.append(element)
    写入文档:tree.write(‘default.xml’, encoding=‘utf-8’, xml_declaration=True)

    VOC数据集类别提取

    提取VOC数据集中的特定类别;
    思路:将符合需要提取的类别的坐标值等相关类容保存到另一个xml文件

    import xml.etree.ElementTree as ET
    import os
    import shutil
    
    """
    VOC类别提取:
    1、读取文件
    2、写入文件,
    时间:2022.04.07
    作者:余小晖 
    """
    
    def __indent(elem, level=0):
        i = "\n" + level*"\t"
        if len(elem):
            if not elem.text or not elem.text.strip():
                elem.text = i + "\t"
            if not elem.tail or not elem.tail.strip():
                elem.tail = i
            for elem in elem:
                __indent(elem, level+1)
            if not elem.tail or not elem.tail.strip():
                elem.tail = i
        else:
            if level and (not elem.tail or not elem.tail.strip()):
                elem.tail = i
    
    
    def VOC_extra(xml_path, img_path,xml_save_path, img_save_path, name_list, num=1):
        xmls = os.listdir(xml_path)
        for i, xml_file in enumerate(xmls):
            img_name = xml_file.split('.')[0] + '.jpg'  # 获取对应图片名
            tree = ET.parse(xml_path + xml_file)
            root = tree.getroot()
            # list_root = list(root)
            new_root = ET.Element('annotation')
            new_tree = ET.ElementTree(new_root)
    
            size = root.find('size')
            file_name = ET.Element('filename')
            file_name.text = img_name
            new_root.append(file_name)
            new_root.append(size)
            # names = root.findall('name')
            for obj in root.findall('object'):
                name = obj.find('name').text
                if name in name_list:
                    new_root.append(obj)
            if len(new_root.findall('object')) > 0:
                __indent(new_root)
                new_tree.write(xml_save_path + xml_file, encoding='utf-8', xml_declaration=True)
                shutil.copy(img_path + img_name, img_save_path + img_name)
                print('num--------------------------', num)
                num += 1
    
    if __name__ == '__main__':
        voc_classes = ["aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat",
                   "chair", "cow", "diningtable", "dog", "horse", "motorbike", "person", "pottedplant",
                   "sheep", "sofa", "train", "tvmonitor"]
        for name_list in voc_classes:
            file_save_name = name_list+ '_VOCtest2007'  #需要修改
            xml_path = './VOCtest_06-Nov-2007/VOCdevkit/VOC2007/Annotations/'   #改路径
            img_path = './VOCtest_06-Nov-2007/VOCdevkit/VOC2007/JPEGImages/'     #改路径
            xml_save_path = './VOCtest_06-Nov-2007/VOCdevkit/VOC2007/VOC_extra/' + file_save_name+ '/ann_xml/'   #改路径
            img_save_path = './VOCtest_06-Nov-2007/VOCdevkit/VOC2007/VOC_extra/'+ file_save_name+ '/images/'     #改路径
            if not os.path.exists(xml_save_path):
                os.makedirs(xml_save_path)
            if not os.path.exists(img_save_path):
                os.makedirs(img_save_path)
            # name_list = ['aeroplane']  #要提取的类别
            VOC_extra(xml_path, img_path,xml_save_path, img_save_path, name_list, num=1)
    

    来源:CV_51154380

    物联沃分享整理
    物联沃-IOTWORD物联网 » Python读写xml文件

    发表评论