读取只包含标签的xml
什么是XML
XML是可扩展标记语言(Extensible Markup Language)的缩写,其中标记是关键部分。用户可以创建内容,然后使用限定标记标记它,从而使每个单词、短语或块成为可识别、可分类的信息。
标记语言从早起的私有公司和政府制定形式逐渐演变成标准通用标记语言(Standard Generalized Markup Language,SGML)、超文本标记语言(Hypertext Markup Language,HTML),并且最终演变成XML。XML有以下几个特点:
- XML的设计宗旨是传输数据,而非显示数据
- XML的标签没有被预定义,用户需要自行定义标签
- XML被设计为具有自我描述性
- XML是W3C的推荐标准
Python对XML文件的解析
常见的XML编程接口有DOM和SAX,这两种接口处理XML文件的方式不同,使用场合也不同。DOM是由W3C官方提出的标准,它会把整个XML文件读入内存,并将该文件解析成树,我们可以通过访问树的节点的方式访问XML中的标签,但是这种方法占用内存大,解析慢,如果读入文件过大,尽量避免使用这种方法。SAX是事件驱动的,通过在解析XML的过程中触发一个个的事件并调用用户自定义的回调函数来处理XML文件,速度比较快,占用内存少,但是需要用户实现回调函数,因此Python标准库的官方文档中这样介绍SAX:SAX每次只允许你查看文档的一小部分,你无法通过当前获取的元素访问其他元素。Python中提供了很多包支持XML文件的解析,如xml.dom,xml.sax,xml.dom.minidom和xml.etree.ElementTree等,本文重点介绍xml.dom.minidom。
xml.dom.minidom包
xml.dom.minidom是DOM API的极简化实现,比完整版的DOM要简单的多,而且这个包也小得多,下面以movie.xml文件为例进行操作。
<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.dom.minidom.parse方法读入xml文件并解析成DOM树
from xml.dom.minidom import parse
import xml.dom.minidom # 使用minidom解析器打开 XML 文档
DOMTree = xml.dom.minidom.parse("F:/project/Breast/codes/AllXML/aa.xml")
collection = DOMTree.documentElement
if collection.hasAttribute("shelf"):
print("Root element : %s" % collection.getAttribute("shelf")) # 在集合中获取所有电影
movies = collection.getElementsByTagName("movie") # 打印每部电影的详细信息
for movie in movies:
print("*****Movie*****")
if movie.hasAttribute("title"):
print("Title: %s" % movie.getAttribute("title")) type = movie.getElementsByTagName('type')[0]
print("Type: %s" % type.childNodes[0].data)
format = movie.getElementsByTagName('format')[0]
print("Format: %s" % format.childNodes[0].data)
rating = movie.getElementsByTagName('rating')[0]
print("Rating: %s" % rating.childNodes[0].data)
description = movie.getElementsByTagName('description')[0]
print("Description: %s" % description.childNodes[0].data)
以上程序执行结果如下:
Root element : New Arrivals
*****Movie*****
Title: Enemy Behind
Type: War, Thriller
Format: DVD
Rating: PG
Description: Talk about a US-Japan war
*****Movie*****
Title: Transformers
Type: Anime, Science Fiction
Format: DVD
Rating: R
Description: A schientific fiction
*****Movie*****
Title: Trigun
Type: Anime, Action
Format: DVD
Rating: PG
Description: Vash the Stampede!
*****Movie*****
Title: Ishtar
Type: Comedy
Format: VHS
Rating: PG
Description: Viewable boredom
实战—批量修改XML文件
最近在用caffe-ssd训练比赛的数据集,但是官方给的数据集用来标记的XML文件并不是标准格式,一些标签的命名不对,导致无法正确生成lmdb文件,因此需要修改这些标签,下面用Python实现了一个批量修改XML文件的脚本。
# -*- coding:utf-8 -*- import os import xml.dom.minidom xml_file_path = "/home/lyz/data/VOCdevkit/MyDataSet/Annotations/"
lst_label = ["height", "width", "depth"]
lst_dir = os.listdir(xml_file_path) for file_name in lst_dir:
file_path = xml_file_path + file_name
tree = xml.dom.minidom.parse(file_path)
root = tree.documentElement #获取根结点
size_node = root.getElementsByTagName("size")[0]
for size_label in lst_label: #替换size标签下的子节点
child_tag = "img_" + size_label
child_node = size_node.getElementsByTagName(child_tag)[0]
new_node = tree.createElement(size_label)
text = tree.createTextNode(child_node.firstChild.data)
new_node.appendChild(text)
size_node.replaceChild(new_node, child_node) #替换object下的boundingbox节点
lst_obj = root.getElementsByTagName("object")
data = {}
for obj_node in lst_obj:
box_node = obj_node.getElementsByTagName("bounding_box")[0]
new_box_node = tree.createElement("bndbox")
for child_node in box_node.childNodes:
tmp_node = child_node.cloneNode("deep")
new_box_node.appendChild(tmp_node)
x_node = new_box_node.getElementsByTagName("x_left_top")[0]
xmin = x_node.firstChild.data
data["xmin"] = (xmin, x_node)
y_node = new_box_node.getElementsByTagName("y_left_top")[0]
ymin = y_node.firstChild.data
data["ymin"] = (ymin, y_node)
w_node = new_box_node.getElementsByTagName("width")[0]
xmax = str(int(xmin) + int(w_node.firstChild.data))
data["xmax"] = (xmax, w_node)
h_node = new_box_node.getElementsByTagName("height")[0]
ymax = str(int(ymin) + int(h_node.firstChild.data))
data["ymax"] = (ymax, h_node) for k, v in data.items():
new_node = tree.createElement(k)
text = tree.createTextNode(v[0])
new_node.appendChild(text)
new_box_node.replaceChild(new_node, v[1])
obj_node.replaceChild(new_box_node, box_node) with open(file_path, 'w') as f:
tree.writexml(f, indent="\n", addindent="\t", encoding='utf-8') #去掉XML文件头(一些情况下文件头的存在可能导致错误)
lines = []
with open(file_path, 'rb') as f:
lines = f.readlines()[1:]
with open(file_path, 'wb') as f:
f.writelines(lines) print("-----------------done--------------------")
关于writexml方法:indent参数表示在当前节点之前插入的字符,addindent表示在该结点的子节点前插入的字符
读取只包含标签的xml的更多相关文章
- 读取配置文件包含properties和xml文件
读取properties配置文件 /** * 读取配置文件 * @author ll-t150 */ public class Utils { private static Properties pr ...
- 死磕Spring之IoC篇 - 解析自定义标签(XML 文件)
该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读 Spring 版本:5.1. ...
- 19 标签:xml或者html
1 标签:xml或者html 1.1 使用XmlSlurper解析xml groovy处理xml非常容易.XmlSlurper 类用来处理xml.在处理xml方面,还有其他的处理方式,但 ...
- 51Nod 1010 只包含因子2 3 5的数 Label:None
K的因子中只包含2 3 5.满足条件的前10个数是:2,3,4,5,6,8,9,10,12,15. 所有这样的K组成了一个序列S,现在给出一个数n,求S中 >= 给定数的最小的数. 例如:n = ...
- 51Nod--1010 只包含235的数
51Nod: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1010 1010 只包含因子2 3 5的数 基准时间限制:1 ...
- 做参数可以读取参数 保存参数 用xml文件的方式
做参数可以读取参数 保存参数 用xml文件的方式 好处:供不同用户保存适合自己使用的参数
- sql语句读取所有父子标签
select A.HOSPITAL_ID from T_HOSPITAL A connect by prior A.HOSPITAL_ID=A.PARENT_ID start with A.HOSPI ...
- 只包含schema的dll生成和引用方法
工作中,所有的tools里有一个project是只包含若干个schema的工程,研究了一下,发现创建这种只包含schema的dll其实非常简单. 首先,在visual studio-new proje ...
- 1007 正整数分组 1010 只包含因子2 3 5的数 1014 X^2 Mod P 1024 矩阵中不重复的元素 1031 骨牌覆盖
1007 正整数分组 将一堆正整数分为2组,要求2组的和相差最小. 例如:1 2 3 4 5,将1 2 4分为1组,3 5分为1组,两组和相差1,是所有方案中相差最少的. Input 第1行:一个 ...
随机推荐
- cf 【并查集】
http://codeforces.com/contest/1245/problem/D 题意就是:你需要让所有城市都有电,你看也在该城市建电站使他有电,同时你可以链接他与其他城市,使之有电 解决: ...
- 2019年最新50道java基础部分面试题(三)
前21题请看之前的随笔 22.面向对象的特征有哪些方面 计算机软件系统是现实生活中的业务在计算机中的映射,而现实生活中的业务其实就是一个个对象协作的过程.面向对象编程就是按现实业务一样的方式将程序代码 ...
- Go语言系列教程
一 Go介绍与开发环境搭建 01-Go语言简介 02-开发环境搭建 03-Go语言集成开发环境之GoLand安装使用 04-Go语言集成开发环境之VS Code安装使用 05-Go包管理详解 二 Go ...
- 【STM32H7教程】第31章 STM32H7的USART应用之RS485
完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第31章 STM32H7的USART应用之RS48 ...
- java类生命周期,类的“加载,连接,初始化,使用,卸载过程”详解
“ 如果说核心类库的 API 比做数学公式的话,那么 Java 虚拟机的知识就好比公式的推导过程” 每本Java入门书籍在介绍Java这门语言的时候都会提到Java跨平台,“一次解释,到处运行的特点“ ...
- MySQL数据库查询所有表名
查找指定库中所有表名 select table_name from information_schema.tables where table_schema='db_name'; 注:替换db_nam ...
- ros相机标定
没有经过校准的camera拍摄的图片是有畸变的.如下图: 而我们希望得到的图片是这样的 ros中提供了一个程序camera_calibration帮助我们去做校准. 具体怎么校准参考 https:// ...
- RabbitMQ的交换器Exchange之direct(发布与订阅 完全匹配)
1.交换器.用来接收生产者发送的消息并将这些消息路由给服务器中的队列.三种常用的交换器类型,a.direct(发布与订阅 完全匹配).b.fanout(广播).c.topic(主题,规则匹配). 2. ...
- solr集群Server refused connection at: http://127.0.0.1:6060/solr/ego 注册zookeepr自动使用内网ip
引导:适用于各种注册服务,zookeeper和被注册的服务器不在同一ip上,产生的注册了127.0.0.1本地ip地址 在使用solr集群操作的时候,报了如下的错误 org.apache.solr.c ...
- oracle学习笔记(二十一) 程序包
程序包 之前我们调用的dbms_output.put_line(''),dbms_output就是一个程序包 程序包创建语法 1. 声明程序包 --声明程序包中的过程,函数,自定义的类型 --程序包里 ...