python将csv转为xml(相当于list转为xml)

文章目录

  • 前言
  • 一、基于xml.dom.minidom模块实现创建一个XML文档。
    • 1.引入库
    • 2.创建一个文件夹,用来保存转换后的xml文件
    • 3.创建XML的过程
  • 二、基于ElementTree增加xml文件节点
    • 1.引入库
    • 2.增加xml文件节点
  • 三、基于ElementTree修改xml文件节点

前言

网上有许多Python 一键批量将 csv 文件转化成 xml 文件。本来想用随便搜一些博主的代码直接用的,但实际并没有那么顺利>﹏<。看了好多文章都是批量将***.csv转为***.xml。可我需要将一个csv每一行转为多个xml文件,emmm虽然如出一辙,但我还是要花了一下午学了一下如何写xml文件。我先将csv文件读入到list中在操作,如何读入写入csv请看上一篇博文

一、基于xml.dom.minidom模块实现创建一个XML文档。

1.引入库

import os
import xml.dom.minidom

2.创建一个文件夹,用来保存转换后的xml文件

# 创建一个文件夹  用来保存转换后的xml文件
path = os.path.join('xml_file')#其实直接赋值路径也是可以的哈哈
if not os.path.exists(path):#判断括号里的文件是否存在,如果存在返回True	
    os.mkdir(path)#创建目录也就是文件夹

3.创建XML的过程

def csv_to_xml(file_list):#我这里将csv文件的每一行做成list传入的函数中
 	rename = file_list[1][:5]#提取其中一部分可以给xml文件命名
    xml_path=path+'\\'+rename+'.xml'
	doc = xml.dom.minidom.Document() #在内存中创建一个空的文档
	root_node = doc.createElement('annotation') #创建一个根节点annotation对象
	root_node.setAttribute('object', 'coordinate') #设置根节点的属性
	root_node.setAttribute('虫子', '坐标')
	doc.appendChild(root)  #将根节点添加到文档对象中
	
	ranch_node=doc.createElement('object')#创建一个分支
	
	folder_node = doc.createElement('name')#创建一个叶子节点
	folder_value = doc.createTextNode(file_list[3])
	folder_node.appendChild(folder_value)#给叶子节点name设置一个文本节点,用于显示文本内容
	branch_node.appendChild(folder_node)#将叶子节点添加到object分支
	root_node.appendChild(branch_node)#将分支添加到根节点
	#添加位置信息和上面一样的步骤
	folder_node_total= doc.createElement('bndbox')
	branch_node.appendChild(folder_node_total)
	
	current_number = 0
	coordinate=['xmin','ymin','xmax','ymax']
	while current_number < 4:
	    folder_node = doc.createElement(coordinate[current_number])
	    folder_value = doc.createTextNode(file_list[current_number+6])
	    folder_node.appendChild(folder_value)
	    folder_node_total.appendChild(folder_node)
	    branch_node.appendChild(folder_node_total)
	    root_node.appendChild(branch_node)
	    current_number = current_number + 1
	    with open(xml_path,"w", encoding="utf-8") as f:
        	doc.writexml(f, indent='', addindent='\t', newl='\n', encoding="utf-8")
# doc.writexml()第一个参数是目标文件对象,第二个参数是根节点的缩进格式,第三个参数是其他子节点的缩进格式, 第四个参数制定了换行格式,第五个参数制定了xml内容的编码。
# fp = open(xml_path, 'w',encoding="utf-8")
# doc.writexml(fp, indent='', addindent='\t', newl='\n', encoding="utf-8")

通过open()打开也可以读写,运行结果如下
python将csv转为xml(相当于list转为xml)_第1张图片

二、基于ElementTree增加xml文件节点

1.引入库

import os
from xml.etree.ElementTree import Element, ElementTree

2.增加xml文件节点

将csv写入xml文件时,发现如果xml已经存在,再写入的话就会将原来存在的xml给覆盖掉,真是令人费解的问题。我就在想能不能直接在原来xml的基础上增加节点,其实基于xml.dom.minidom模块可以增加节点,嘿嘿,可谁让我这么好学呢,看了一下基于ElementTree写也挺简单的

#但这样写入会有个问题,写入的XML会在同一行,缺少换行符,Etree本身并没有提供换行的选项,看了网上大神的回答,对root处理以后,再次写入将有换行符。      
def __indent(e, level=0):
    if len(e) > 0:
        e.text = '\n' + '\t' * (level + 1)
        child = None
        for child in e:
            __indent(child, level + 1)
        child.tail = child.tail[:-1]
    e.tail = '\n' + '\t' * level
网上两个加换行符的,选择用其中一个就可以了
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 if_xml_exist(file_list):
    rename = file_list[1][:5]#提取其中一部分可以给xml文件命名
    xml_path=path+'\\'+rename+'.xml'
    if (os.path.exists(xml_path)):如果新命名的xml文件已经存在就追加写入xml文件中
        tree=ElementTree()#遍历整个文档树用ElementTree,遍历单独的节点或者子节点用Element
        tree.parse(xml_path) #打开xml文件
        root_node=tree.getroot()#获取根节点
        element=Element('object')#创建第一个分支#element=Element('object',{}) #{}里面是字典,还可以给节点添加属性
        folder_node=Element('name')#创建第二个分支
        folder_node.text=file_list[3]#写入第二分支的值
        element.append(folder_node)将第二分支加入到第一个分支

        folder_node_all_location=Element('bndbox')##添加位置信息和上面一样的步骤
        element.append(folder_node_all_location)

        current_number = 0
        coordinate=['xmin','ymin','xmax','ymax']
        while current_number < 4:
            folder_node_location =Element(coordinate[current_number])
            folder_node_location.text = file_list[current_number + 6]
            folder_node_all_location.append(folder_node_location)
            current_number = current_number + 1
        root_node.append(element)
        __indent(root_node)
        tree.write(xml_path, encoding='utf-8', xml_declaration=True)a

三、基于ElementTree修改xml文件节点

在目标检测对图片打标签时,不小心打错了标签的’name’,如果从新再来就太浪费时间,就想着应该可以直接批量修改xml的节点内容,有点懒>︿<,基于xml.dom.minidom模块不想写了,下次我遇到在更新吧

from xml.etree.ElementTree import Element, ElementTree
import os

list=[]
file_path='存放xml文件的路径'
all_xml_file = os.listdir(file_path)
for xml_file in all_xml_name:
    xml_path=file_path+'\\'+xml_file
    tree=ElementTree()
    tree.parse(xml_path)
    root_node=tree.getroot()
    
    # root_node.findall可将根节点所有'object'存放到list
    # root_node.find只返回根节点的第一个'object'
    branch_node=root_node.findall('object')
    for branch in branch_node:
        folder_node=branch.find('name') # 找到打错标签的'name'
        folder_node.text = insect_name  # 修改标签内容
        tree.write(xml_path, encoding='utf-8', xml_declaration=True)

你可能感兴趣的:(xml,python,list)