欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

python 处理xml文件

程序员文章站 2022-03-03 18:50:31
XML可扩展标记语言(eXtensible Markup Language),被设计用来传输和存储数据。 Tove Jani Reminder Don't forget me this weekend!...

XML可扩展标记语言(eXtensible Markup Language),被设计用来传输和存储数据。

<?xml version="1.0" encoding="UTF-8"?> <note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note> 

xml文档形成了一种树解构,它从根部开始,然后扩展到枝叶。在上面的文档中,第一行是xml的声明,定义了xml的版本和使用的编码方式。第二行描述文档的根元素(类似于本文档是一个note),接下来有4个子元素,(to,from,heading,body)。
例如下面的xml文档表示bookstore

<bookstore> <book category="COOKING"> <title lang="en">Everyday Italian</title> <author>Giada De Laurentiis</author> <year>2005</year> <price>30.00</price> </book> <book category="CHILDREN"> <title lang="en">Harry Potter</title> <author>J K. Rowling</author> <year>2005</year> <price>29.99</price> </book> <book category="WEB"> <title lang="en">Learning XML</title> <author>Erik T. Ray</author> <year>2003</year> <price>39.95</price> </book> </bookstore> 

语法结构

xml的声明中,省略关闭标签是非法的。所有元素都必须有关闭标签,类似于


xml标签对大小写敏感,xml必须正确嵌套,xml的属性值必须加上引号。例如
<note date="12/11/2007"> <to>Tove</to> <from>Jani</from> </note> 

xml中的字符拥有特殊的意义,xml中存在5个实体引用

  • &lt <
  • &gt >
  • &amp &
  • &apos ’
  • &quot "

xml的注释语法如下,和html语法一样。

<!-- This is a comment --> 

xml中空格会被保留,xml以LF存储换行。

python对xml文件解析

常见的xml编程接口有DOM和SAX,这两种接口处理xml文件方式不同。python中有三种方法解析xml,sax,dom一级ElementTree

1.SAX (simple API for XML )

Python 标准库包含 SAX 解析器,SAX 用事件驱动模型,通过在解析XML的过程中触发一个个的事件并调用用户定义的回调函数来处理XML文件。

2.DOM(Document Object Model)

将 XML 数据在内存中解析成一个树,通过对树的操作来操作XML。

3.ElementTree(元素树)

ElementTree就像一个轻量级的DOM,具有方便友好的API。代码可用性好,速度快,消耗内存少。

注:因DOM需要将XML数据映射到内存中的树,一是比较慢,二是比较耗内存,而SAX流式读取XML文件,比较快,占用内存少,但需要用户实现回调函数(handler)。

解析实例:

<collection shelf="New Arrivals"> <movie title="Enemy Behind"> <type>War, Thriller</type> <format>DVD</format> <year>2003</year> <rating>PG</rating> <stars>10</stars> <description>Talk about a US-Japan war</description> </movie> <movie title="Transformers"> <type>Anime, Science Fiction</type> <format>DVD</format> <year>1989</year> <rating>R</rating> <stars>8</stars> <description>A schientific fiction</description> </movie> <movie title="Trigun"> <type>Anime, Action</type> <format>DVD</format> <episodes>4</episodes> <rating>PG</rating> <stars>10</stars> <description>Vash the Stampede!</description> </movie> <movie title="Ishtar"> <type>Comedy</type> <format>VHS</format> <rating>PG</rating> <stars>2</stars> <description>Viewable boredom</description> </movie> </collection> 

xml处理子模块包括:

  • xml.etree.ElementTree: ElementTree API,一个简单而轻量级的XML处理器

  • xml.dom:DOM API 定义

  • xml.dom.minidom:最小的 DOM 实现

  • xml.dom.pulldom:支持构建部分 DOM 树

  • xml.sax:SAX2 基类和便利函数

  • xml.parsers.expat:Expat解析器绑定

ET模块解析xml文件

其中xml.etree.ElementTree模块实现了简单高效的API,可以用来解析和创建XML数据。
Element对象有下面的常用属性:

  • Element.tag 标签
  • Element.text,去除标签,获取标签中的内容。
    例如
  • Element.attrib,获取标签中的属性和属性值
  • Element.findall(),找到带有标签的所有节点
  • Element.append(),增加新的节点
  • Element.set(),增加或者修改属性
  • Element.remove(),删除节点。
  • ElementTree.write()保存xml文件。

参考官方python的结构化标准处理工具XML
对于下面的示例xml文档:

<?xml version="1.0"?> <data> <country name="Liechtenstein"> <rank>1</rank> <year>2008</year> <gdppc>141100</gdppc> <neighbor name="Austria" direction="E"/> <neighbor name="Switzerland" direction="W"/> </country> <country name="Singapore"> <rank>4</rank> <year>2011</year> <gdppc>59900</gdppc> <neighbor name="Malaysia" direction="N"/> </country> <country name="Panama"> <rank>68</rank> <year>2011</year> <gdppc>13600</gdppc> <neighbor name="Costa Rica" direction="W"/> <neighbor name="Colombia" direction="E"/> </country> </data> 
>>> for country in root.findall('country'): ... rank = country.find('rank').text ... name = country.get('name') ... print(name, rank) ... Liechtenstein 1 Singapore 4 Panama 68 

例如下面voc标注的数据,格式为xml文件:

<annotation verified="yes"> <folder>Annotation</folder> <filename>invoice_direction_0_0.jpg</filename> <path>invoice_stamp-PascalVOC-export/Annotations/invoice_direction_0_0.jpg</path> <source> <database>Unknown</database> </source> <size> <width>2962</width> <height>1753</height> <depth>3</depth> </size> <segmented>0</segmented> <object> <name>stamp</name> <pose>Unspecified</pose> <truncated>0</truncated> <difficult>0</difficult> <bndbox> <xmin>1872.3010033444816</xmin> <ymin>1216.3294491525423</ymin> <xmax>2370.9208472686732</xmax> <ymax>1579.474458568738</ymax> </bndbox> </object><object> <name>stamp</name> <pose>Unspecified</pose> <truncated>0</truncated> <difficult>0</difficult> <bndbox> <xmin>1152.4392419175028</xmin> <ymin>123.59310263653484</ymin> <xmax>1505.7658862876256</xmax> <ymax>351.3840630885122</ymax> </bndbox> </object> </annotation> 
import xml.etree.ElementTree as ET import os from PIL import Image, ImageDraw, ImageFont def parse_rec(filename): tree = ET.parse(filename) # 解析读取xml函数 objects = [] img_dir =[] # Element.findall()查找当前元素的直接子元素中带有指定标签的元素 # Element.find()找带有特定标签的第一个子级 # Elemtn.text 访问元素的文本内容 # Element.get 访问元素的属性。 for xml_name in tree.findall('filename'): img_path = os.path.join(pic_path, xml_name.text) img_dir.append(img_path) for obj in tree.findall('object'): obj_struct = {} obj_struct['name'] = obj.find('name').text
		obj_struct['pose'] = obj.find('pose').text
		obj_struct['truncated'] = int(obj.find('truncated').text) obj_struct['difficult'] = int(obj.find('difficult').text) bbox = obj.find('bndbox') obj_struct['bbox'] = [int(bbox.find('xmin').text), int(bbox.find('ymin').text), int(bbox.find('xmax').text), int(bbox.find('ymax').text)] objects.append(obj_struct) return objects,img_dir #	可视化目标框,并显示标签 def visualise_gt(objects,img_dir): for id,img_path in enumerate(img_dir): img = Image.open(img_path) draw = ImageDraw.Draw(img) for a in objects: xmin =int(a['bbox'][0]) ymin =int(a['bbox'][1]) xmax =int(a['bbox'][2]) ymax =int(a['bbox'][3]) label = a['name'] draw.rectangle((xmin,ymin,xmax,ymax), fill=None, outline=(0,255,0),width=2) draw.text((xmin-10,ymin-15), label, fill = (0,255,0),font=font) # 利用ImageDraw的内置函数,在图片上写入文字 img.show() fontPath = "C:\Windows\Fonts\Consolas\consola.ttf" # 字体路径 root = 'F:/dataset/AQM' ann_path = os.path.join(root, 'Annotations') # xml文件所在路径 pic_path = os.path.join(root, 'JPEGImages') # 样本图片路径 font = ImageFont.truetype(fontPath, 16) for filename in os.listdir(ann_path): xml_path = os.path.join(ann_path,filename) object,img_dir = parse_rec(xml_path) visualise_gt(object,img_dir ) 

参考:CSDN博客 - - python xml 格式的数据集标注文件解析

本文地址:https://blog.csdn.net/xinming_365/article/details/109039354

相关标签: python