如何将xml文件转txt (xml指定提取)

1.主要内容和目的

本文主要记录下自己将xml文件中有用的数据提取至txt的过程。在查找代码时发现,大都复制粘贴的代码,不仅冗余,而且晦涩难懂,于是自己整理了一套代码。不多说,直接图解。
如何将xml文件转txt (xml指定提取)_第1张图片

2.我的xml文件如下:

大家的xml文件大同小异,可以耐心看完,自己就会改了。

<annotation>
	<folder>UAV_datafolder>
	<filename>anju _19.jpgfilename>
	<source>
		<database>The UAV autolandingdatabase>
		<annotation>UAV AutoLandingannotation>
		<image>flickrimage>
		<flickrid>NULLflickrid>
	source>
	<owner>
		<flickrid>NULLflickrid>
		<name>ChaojieZhuname>
	owner>
	<size>
		<width>1080width>
		<height>1080height>
		<depth>3depth>
	size>
		<segmented>0segmented>
	<object>
		<name>parksetname>
		<pose>Unspecifiedpose>
		<truncated>1truncated>
		<difficult>0difficult>
		<bndbox>
			<xmin>0.0xmin>
			<ymin>422.0ymin>
			<xmax>347.1904761904762xmax>
			<ymax>626.0ymax>
		bndbox>
		<keypoints>
			<x0>323.0x0>
			<y0>626.0y0>
			<x1>347.1904761904762x1>
			<y1>463.4920634920635y1>
			<x2>0.0x2>
			<y2>422.0y2>
			<x3>0.0x3>
			<y3>589.0y3>
		keypoints>
	object>
	<object>
		<name>wheel_stoppername>
		<pose>Unspecifiedpose>
		<truncated>1truncated>
		<difficult>0difficult>
		<bndbox>
			<xmin>782.0408163265306xmin>
			<ymin>514.2857142857142ymin>
			<xmax>986.937984496124xmax>
			<ymax>658.1395348837209ymax>
		bndbox>
		<keypoints>
			<x0>793.0612244897959x0>
			<y0>514.2857142857142y0>
			<x1>782.0408163265306x1>
			<y1>645.3061224489795y1>
			<x2>976.8604651162791x2>
			<y2>658.1395348837209y2>
			<x3>986.937984496124x3>
			<y3>537.2093023255813y3>
		keypoints>
	object>
	<object>
		<name>wheel_stoppername>
		<pose>Unspecifiedpose>
		<truncated>1truncated>
		<difficult>0difficult>
		<bndbox>
			<xmin>765.8959537572255xmin>
			<ymin>660.1156069364162ymin>
			<xmax>977.4193548387096xmax>
			<ymax>812.9032258064516ymax>
		bndbox>
		<keypoints>
			<x0>780.9248554913295x0>
			<y0>660.1156069364162y0>
			<x1>765.8959537572255x1>
			<y1>795.9537572254335y1>
			<x2>954.8387096774193x2>
			<y2>812.9032258064516y2>
			<x3>977.4193548387096x3>
			<y3>673.5483870967741y3>
		keypoints>
	object>
	<object>
		<name>wheel_stoppername>
		<pose>Unspecifiedpose>
		<truncated>1truncated>
		<difficult>0difficult>
		<bndbox>
			<xmin>9.418604651162795xmin>
			<ymin>437.2093023255814ymin>
			<xmax>66.21621621621621xmax>
			<ymax>483.3333333333333ymax>
		bndbox>
		<keypoints>
			<x0>62.61261261261261x0>
			<y0>483.3333333333333y0>
			<x1>66.21621621621621x1>
			<y1>442.79279279279274y1>
			<x2>11.74418604651163x2>
			<y2>437.2093023255814y2>
			<x3>9.418604651162795x3>
			<y3>472.09302325581393y3>
		keypoints>

我是想得到 filename 中的anju_19.jpg以及 keypoints中x0 y0 x1 y1这些数据点,并在txt中间断空格保存。那么问题来了,如何解析呢,下面付了代码并做出了解释。

2.我的代码如下:

我知道你最想要的是代码,那么代码如下,。。。。
等等确定不看下 下面解释来理解一下原理嘛。 保你看懂哦,看懂看到任何xml转格式和提取再也不怕啦。

#from os import listdir, getcwd
#from os.path import join
import cv2
import os
from xml.etree.ElementTree import parse

xmlfilepath='D:\\destop\\dst\\xml\\' #你的xml文件夹路径,不是xml文件,批量处理时用

total_xml = os.listdir(xmlfilepath)#遍历xml文件
for xml in total_xml:

    xml_path=os.path.join(xmlfilepath,xml)#xml的全路径,也就是文件的路径
    print(xml_path)

    tree = parse(xml_path)  #获取ElementTree
    root = tree.getroot()   #获取根元素

    filename = root.findtext('filename')#提取到了xml对应的 filename的名字
    
    print('filename:',filename)
    for obj in root.iter('object'):#看上面xml文件可知我想要的keypoints在object这个标签下,而且有很多object ,因此我要遍历object
        print('obj:',str(obj))
        cls = obj.find('name').text#将解析得到该keypoints下 name中的标签,也就是wheel_stopper类
        print('cls:',cls)
        if cls=='wheel_stopper': #由与还有标签parkset类 而我只想要wheel_stopper类别下的x0 y0....
            

            xmlbox = obj.find('keypoints')  #此时得到了想要的点x0,y0,x1,y1,
            b = ((xmlbox.find('x0').text), (xmlbox.find('y0').text),
                ( xmlbox.find('x1').text), (xmlbox.find('y1').text))
            with open('D:\\destop\\dst\\1.txt','a') as f:#不用创建,自己存一个路径 我这里是1.txt 那你呢。。你定吧
                f.write(str(filename))
                print("b:",b[0])
                for i in range(len(b)):
                    f.write(' ')
                    f.write(str(b[i]))
                f.write('\n')

重要的要理解

root = tree.getroot()   #获取根元素

filename = root.findtext('filename')#提取到了xml对应的 filename的名字

如何将xml文件转txt (xml指定提取)_第2张图片

上述代码root就是将xml加载解析了,而filename(上图红色箭头指向)相当于一级目录,这个一级目录下就他自己,用root.findtext(‘filename’)即可解析得到。
如何将xml文件转txt (xml指定提取)_第3张图片

3 通俗讲解

暂且通俗易懂的叫object为一级目录,想得到的x0,y0,x1,y1在object下的keypoints中,
这相当于keypoints是二级目录,如果想要得到Xmin Ymin就将 keypoints换为bndbox即可。
看上图蓝色箭头知道object不止一个呀,咋办哦, 那就遍历所有object,于是下面代码相当于遍历了一遍一级目录 ‘object’,于是可以可以得到二级目录运用obj.find(‘name’)这里name可以替换成任意二级目录
敲黑板啦,你的name应该是你要的类别,你的name可能不是我的wheel_stopper,可能是car ,person,dog等一些类别标签,注意替换哦。这里我只想要wheel_stopper,所以你想要啥标签可以自己写下,也可以找我帮你嘛

for obj in root.iter('object'):#看上面xml文件可知我想要的keypoints在object这个标签下,而且有很多object ,因此我要遍历object
        print('obj:',str(obj))
        cls = obj.find('name').text#将解析得到该keypoints下 name中的标签,也就是wheel_stopper类
        print('cls:',cls)
        if cls=='wheel_stopper': #由与还有标签parkset类 而我只想要wheel_stopper类别下的x0 y0....
            

            xmlbox = obj.find('keypoints')  #此时得到了想要的点x0,y0,x1,y1,
            b = ((xmlbox.find('x0').text), (xmlbox.find('y0').text),
                ( xmlbox.find('x1').text), (xmlbox.find('y1').text))

运用 xmlbox = obj.find(‘keypoints’) #此时得到了想要的点x0,y0,x1,y1,
运用xmlbox.find(‘x0’).text),就可以得到X0数据,以此类推。

with open('D:\\destop\\dst\\1.txt','a') as f:#不用创建,自己存一个路径 我这里是1.txt 那你呢。。你定吧

这里的目的是创建一个txt存取 提取的x0,y0等

4 结果

最终得到了数据如下图:
如何将xml文件转txt (xml指定提取)_第4张图片
我这个文件夹就有一个xml文件 所以只有一个名字,并且没有将数据写在一行,你可以更改的哦,我后面需要的时候更改啦

怎么样,不知道讲清楚了没。
如果对你有帮助,还希望一键三连啊。

欢迎被代码困住的 被debug缠身的小伙伴交流解决,视觉相关代码,单目测距,论文撰写,(yolo,presacn,matlab,c++)皆可交流哦------------------------!

你可能感兴趣的:(数据处理,xml2txt,python,xml,python,sublime,text)