
- 前言
- 一、基于xml.dom.minidom模块实现创建一个XML文档。
- 1.引入库
- 2.创建一个文件夹,用来保存转换后的xml文件
- 3.创建XML的过程
- 二、基于ElementTree增加xml文件节点
- 1.引入库
- 2.增加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):
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','yamx']
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()也可以,运行结果如下
import os
from xml.etree.ElementTree import Element, ElementTree
2.增加xml文件节点
将csv写入xml文件时,发现如果xml已经存在,再写入的话就会将原来存在的xml给覆盖掉,真是令人费解的问题。我就在想能不能直接在原来xml的基础上增加节点,其实基于xml.dom.minidom模块可以增加节点,嘿嘿,可谁让我这么好学呢,看了一下基于ElementTree写也挺简单的
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
#但这样写入会有个问题,写入的XML会在同一行,缺少换行符,Etree本身并没有提供换行的选项,看了网上大神的回答,对root处理以后,再次写入将有换行符。
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
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)
return
但是用最后两行代码通过open打开写入xml文件的话就会报错xml.etree.ElementTree.ParseError: not well-formed (invalid token,很是奇怪,由于本人才疏学浅,也不知道到底怎么改。不过通过with open() as f语句就可以正常运行,
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)