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

2 篇文章 0 订阅
1 篇文章 0 订阅

1.主要内容和目的

本文主要记录下自己将xml文件中有用的数据提取至txt的过程。在查找代码时发现,大都复制粘贴的代码,不仅冗余,而且晦涩难懂,于是自己整理了一套代码。不多说,直接图解。
在这里插入图片描述

2.我的xml文件如下:

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

<annotation>
	<folder>UAV_data</folder>
	<filename>anju _19.jpg</filename>
	<source>
		<database>The UAV autolanding</database>
		<annotation>UAV AutoLanding</annotation>
		<image>flickr</image>
		<flickrid>NULL</flickrid>
	</source>
	<owner>
		<flickrid>NULL</flickrid>
		<name>ChaojieZhu</name>
	</owner>
	<size>
		<width>1080</width>
		<height>1080</height>
		<depth>3</depth>
	</size>
		<segmented>0</segmented>
	<object>
		<name>parkset</name>
		<pose>Unspecified</pose>
		<truncated>1</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>0.0</xmin>
			<ymin>422.0</ymin>
			<xmax>347.1904761904762</xmax>
			<ymax>626.0</ymax>
		</bndbox>
		<keypoints>
			<x0>323.0</x0>
			<y0>626.0</y0>
			<x1>347.1904761904762</x1>
			<y1>463.4920634920635</y1>
			<x2>0.0</x2>
			<y2>422.0</y2>
			<x3>0.0</x3>
			<y3>589.0</y3>
		</keypoints>
	</object>
	<object>
		<name>wheel_stopper</name>
		<pose>Unspecified</pose>
		<truncated>1</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>782.0408163265306</xmin>
			<ymin>514.2857142857142</ymin>
			<xmax>986.937984496124</xmax>
			<ymax>658.1395348837209</ymax>
		</bndbox>
		<keypoints>
			<x0>793.0612244897959</x0>
			<y0>514.2857142857142</y0>
			<x1>782.0408163265306</x1>
			<y1>645.3061224489795</y1>
			<x2>976.8604651162791</x2>
			<y2>658.1395348837209</y2>
			<x3>986.937984496124</x3>
			<y3>537.2093023255813</y3>
		</keypoints>
	</object>
	<object>
		<name>wheel_stopper</name>
		<pose>Unspecified</pose>
		<truncated>1</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>765.8959537572255</xmin>
			<ymin>660.1156069364162</ymin>
			<xmax>977.4193548387096</xmax>
			<ymax>812.9032258064516</ymax>
		</bndbox>
		<keypoints>
			<x0>780.9248554913295</x0>
			<y0>660.1156069364162</y0>
			<x1>765.8959537572255</x1>
			<y1>795.9537572254335</y1>
			<x2>954.8387096774193</x2>
			<y2>812.9032258064516</y2>
			<x3>977.4193548387096</x3>
			<y3>673.5483870967741</y3>
		</keypoints>
	</object>
	<object>
		<name>wheel_stopper</name>
		<pose>Unspecified</pose>
		<truncated>1</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>9.418604651162795</xmin>
			<ymin>437.2093023255814</ymin>
			<xmax>66.21621621621621</xmax>
			<ymax>483.3333333333333</ymax>
		</bndbox>
		<keypoints>
			<x0>62.61261261261261</x0>
			<y0>483.3333333333333</y0>
			<x1>66.21621621621621</x1>
			<y1>442.79279279279274</y1>
			<x2>11.74418604651163</x2>
			<y2>437.2093023255814</y2>
			<x3>9.418604651162795</x3>
			<y3>472.09302325581393</y3>
		</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的名字

在这里插入图片描述

上述代码root就是将xml加载解析了,而filename(上图红色箭头指向)相当于一级目录,这个一级目录下就他自己,用root.findtext(‘filename’)即可解析得到。
在这里插入图片描述

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文件 所以只有一个名字,并且没有将数据写在一行,你可以更改的哦,我后面需要的时候更改啦

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

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

  • 11
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿利同学

一角两角不嫌少

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值