Python取出xml文件中的部分内容

Python取出xml文件中的部分内容

前言

​ 最近在搞目标检测方面的东西,由于遇到有个项目需要的标签格式为txt格式的,而我之前用labelimg工具标注生成的是xml格式的文件,由于懒,就想找个脚本自动提取出我想要的信息,但是并没有找到合适的,后来在参考了几位博主的文章后逐渐懂得如何取出我自己想要的内容。

正文

我的xml示例如下(我命名为1.xml):

<annotation>
	<folder>poses</folder>
	<filename>1.jpg</filename>
	<path>D:\pycharm\Graduate_design\poses\1.jpg</path>
	<source>
		<database>Unknown</database>
	</source>
	<size>
		<width>640</width>
		<height>480</height>
		<depth>3</depth>
	</size>
	<segmented>0</segmented>
	<object>
		<name>forward</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>241</xmin>
			<ymin>85</ymin>
			<xmax>436</xmax>
			<ymax>404</ymax>
		</bndbox>
	</object>
</annotation>

假设我想要取出的是:

1.<size 标签中的width、height以及depth后面对应的640,480,3;

2.<object 中的name字段。

3.<bndbox 中的xmin、ymin、xmax、ymax对应的内容;

代码:

import os
import xml.dom.minidom

#获取xml文件地址
path = os.path.abspath('.') 
data_path = os.path.join(path,'./1.xml') #获取xml文件地址

DOMTree = xml.dom.minidom.parse(data_path)
data = DOMTree.documentElement

# style = xml中的大类 ; typename = 细分属性; typevalue = 细分属性的值; valuename = xml文件,需要获取的值的tag;
def get_data_vaule(style, typename, typevalue, valuename):
    nodelist = data.getElementsByTagName(style) # 根据标签的名字获得节点列表

    for node in nodelist: 
        if typevalue == node.getAttribute(typename):
            node_name = node.getElementsByTagName(valuename)
            value = node_name[0].childNodes[0].nodeValue
            return value
    return

width = get_data_vaule('size',"","",'width')
print('width:',width)
height = get_data_vaule('size',"","",'height')
print('height:',height)
depth = get_data_vaule('size',"","",'depth')
print('width:',depth)

class_name = get_data_vaule('object',"","",'name')
print('class_name:',class_name)

xmin = get_data_vaule('bndbox',"","",'xmin')
print('xmin:',xmin)
ymin = get_data_vaule('bndbox',"","",'ymin')
print('ymin:',ymin)
xmax = get_data_vaule('bndbox',"","",'xmax')
print('xmax:',xmax)
ymax = get_data_vaule('bndbox',"","",'ymax')
print('ymax:',ymax)

结果:

image-20220328152759938

可以看到成功取出了我想要的内容。

参考资料

1.https://blog.csdn.net/weixin_39008941/article/details/76037730?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~default-0.topblog&spm=1001.2101.3001.4242.1&utm_relevant_index=3


下面这部分可以不用看了,只是我把前面提取出来的数据经过处理之后存入txt而已,我就想方便自己查找(狗头)

import os
import xml.dom.minidom

#获取xml文件地址
path = os.path.abspath('.') 
data_path = os.path.join(path,'./1.xml') #获取xml文件地址

DOMTree = xml.dom.minidom.parse(data_path)
data = DOMTree.documentElement

# style = xml中的大类 ; typename = 细分属性; typevalue = 细分属性的值; valuename = xml文件,需要获取的值的tag;
def get_data_vaule(style, typename, typevalue, valuename):
    nodelist = data.getElementsByTagName(style) # 根据标签的名字获得节点列表

    for node in nodelist: 
        if typevalue == node.getAttribute(typename):
            node_name = node.getElementsByTagName(valuename)
            value = node_name[0].childNodes[0].nodeValue
            return value
    return

class_name = get_data_vaule('object',"","",'name')
print('class_name:',class_name)

width = get_data_vaule('size',"","",'width')
print('width:',width)
height = get_data_vaule('size',"","",'height')
print('height:',height)

xmin = get_data_vaule('bndbox',"","",'xmin')
print('xmin:',xmin)
ymin = get_data_vaule('bndbox',"","",'ymin')
print('ymin:',ymin)
xmax = get_data_vaule('bndbox',"","",'xmax')
print('xmax:',xmax)
ymax = get_data_vaule('bndbox',"","",'ymax')
print('ymax:',ymax)

class_dict = {0:'backward',1:'forward',2:'left',3:'right',4:'speed_down',5:'speed_up',6:'stop'}
print(class_dict.values())
print(class_dict.keys())
# 根据值找键,如果有多个值一样,则只返回第一个找到的
label_index = list(class_dict.keys())[list(class_dict.values()).index(class_name)]
print(label_index)

# 先把前面提取出来的坐标转换为整型,前面提取出来的是字符串类型
xmin = int(xmin)
xmax = int(xmax)
ymin = int(ymin)
ymax = int(ymax)
width = int(width)
height = int(height)

# 目标txt格式: label_index,Cx,Cy,width,height(后4个是经过归一化的)
# Cx, Cy是标准化标签框中心点的坐标
Cx = ((xmax - xmin)/2)/width
Cy = ((ymax - ymin)/2)/height
norm_w = (xmax - xmin)/width
norm_h = (ymax - ymin)/height
print('----------')
print('label_index:',label_index)
print('Cx:',Cx)
print('Cy:',Cy)
print('norm_w:',norm_w)
print('norm_h:',norm_h)

write_data = [label_index,Cx,Cy,norm_w,norm_h]

# 将上面的数据写入txt中
txt_path = './txt/'
start = 1

path_file_name = txt_path+str(start)+'.txt'
if not os.path.exists(path_file_name):
    with open(path_file_name, "w") as f:
        print(f)

with open(path_file_name, "w") as f:
    for data in write_data:
        f.write(str(data))
        f.write(' ')  # 将空格写入txt文件中以分隔数据

print('finished!')

在这里插入图片描述

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值