做目标检测之际, 我们获取到图片的xml文件, 我们期望借助xml文件解析得出我们所需的信息, 或者我们打算对xml文件进行一些修改, 下面我会利用自带的xml包去完成这一系列的操作, 其实还有一个用于解析HTML的包lxml也能够解读xml文件, 也是相当好用的, 具体的使用方法能够参看这篇博客, 参考网站我置放在底部, 里面讲述得也极为详细, 本文用来演示的xml模板结构状如以下图形:
一、读取并解析xml文件
我们主要使用的模块是xml.etree.
1、解析xml——获取xml树
importxml.etree.ElementTree as ET file_xml='/home/g4/桌面/project/xxxx/99.xml' # xml文件路径 tree = ET.parse(file_xml) type(tree)
xml.etree.ElementTree.ElementTree
这里, tree的对象如是, 从名字能够晓得这个数据结构跟多叉树相类似, 我们借助dir()能够查看这个类的属性以及方法。
dir(tree)
['__class__','__delattr__','__dict__','__dir__','__doc__','__eq__','__format__','__ge__','__getattribute__','__gt__','__hash__','__init__','__init_subclass__','__le__','__lt__','__module__','__ne__','__new__','__reduce__','__reduce_ex__','__repr__','__setattr__','__sizeof__','__str__','__subclasshook__','__weakref__','_root','_setroot','find','findall','findtext','getiterator','getroot','iter','iterfind','parse','write','write_c14n']
在这里, 我们能够看见其中存在find方法, 该方法, 随后将会被讲到, 其使用方式。
我们接下来要获取其根节点,以及其他节点的内容。
2、解析xml——获取子节点及其节点内容
得到一棵树之后的我们, 我们借助tree的()方法去获取整颗树的根结点。
root =tree.getroot() type(root)xml.etree.ElementTree.Element
dir(root)['__class__','__copy__','__deepcopy__','__delattr__','__delitem__','__dir__','__doc__','__eq__','__format__','__ge__','__getattribute__','__getitem__','__getstate__','__gt__','__hash__','__init__','__init_subclass__','__le__','__len__','__lt__','__ne__','__new__','__reduce__','__reduce_ex__','__repr__','__setattr__','__setitem__','__setstate__','__sizeof__','__str__','__subclasshook__','append','attrib','clear','extend','find','findall','findtext','get','getchildren','getiterator','insert','items','iter','iterfind','itertext','keys','makeelement','remove','set','tag','tail','text']
我们能够瞧见根结点的数据类型为, 实际上这棵树的全部节点数据类型皆是, 接下来讲述这些方式以及特性。
root.find('xxx'), 返回的是一个对象, 此对象是在该节点下提取出名为‘xxx’的那个字节点, 若存在多个名为xxx的子节点, 将会返回首个。root.('xxx'), 返回值是一个列表, 列表的每个元素是, 即返回该节点下叫做‘xxx’的所有子节点, 用list来储存。root. , 返回该所有的“属性”, 是一个字典, 该节点的“属性”就是, 一会结合示例xml文件, 可看到具体的返回值。返回的是一个字符串, 此字符串是这个根节点所包含的内容, 而这也就是xxxx中的xxxx , 它由root.text标识。
随后, 我们依据文章起始部分所给的示例 xml, 去呈现一下上面所介绍的方法以及属性。
path = root.find('path') # 获取root节点(annotation)下的叫做path的这个节点 type(path)
xml.etree.ElementTree.Element
root.attrib # 获取annotation节点的属性(包含有两个属性一个是name,一个是id){'name':'Panama','id':'1234'}path.text # 获取path节点的内容'百度'
root.findall('object')
['object'at 0x7fd9adcec110>, 'object'at 0x7fd9adcecbf0>]
能瞧见, 在第一行里, 我们得到了root的字节点path, 这path还是一种类别, 所以呢, 它同样具备前面所提及的那些方法以及属性。
能够瞧一瞧最后一行的那个给出来、返回的列表, 其中存有的元素所展示的是节点以内存地址形式存在的情况。之前讲过tree也存在方法 , 实际上要是运用tree的(' ')所取得的结果同样是这样的。
tree.findall('object')
['object'at 0x7fd9adcec110>, 'object'at 0x7fd9adcecbf0>]
我们能够看见, 内存地址同样是这样的, 所以, 借助这两种办法, 去进行搜索, 进而得到的子节点是完全相同的。
二、修改xml文件
历经过程, 我们已然能够将xml之中的信息予以提取, 紧接着, 我们能够针对获取得到的xml文件里的相关信息实施修改。
1、修改节点内容
要是想要去修改节点的内容, 我们能够直接采用.text = 'xxxx', 如此这般, 便能够达成修改的操作了。
path.text ='修改后'path= root.find('path') path.text
'修改后'
上面举的例子表明, path节点的text, 已然从起初的‘百度’转变为了‘修改后’, 而且在再度从root里获取该path节点时, 呈现的同样是修改过后的状况, 因而修改节点内容是极为简便省事的。
2、修改节点属性
新增节点属性。.set(新属性名,新值)
root.set('sex','男') root.attrib
{'name':'Panama','id':'1234','sex':'男'}运用使用里的set方法, 来对节点的属性予以修改。该方法为.set, 括号内依次是待修改的属性名, 还有新值。
root.set('id','4321') root.attrib
{'name':'Panama','id':'4321','sex':'男'}可以看到root的id这个属性已经被修改成了4321。
(删除属性值,我还没找到对应的方法。。。。)
3、删除和增加子节点
如果要在一个下新一个子节点,我们采用.()的方式。
path = root.find('path') path.findall('object')
[]
obj= root.find('object') path.append(obj) path.findall('object')
['object'at 0x7fd9adcec110>]
能瞧见, 于path之下, 原本并无此子节点, 然而在那之后便有了, 需留意的是, 我们唯有身为对象。
删除一个子节点采用的是.()的方式。
path.remove(obj) path.findall('object')
[]
也要注意的是参数只能是对象并且还得是同一个内存。
obj = root.findall('object')[1] path.remove(obj)
ValueError: list.remove(x): xnotinlist
要是我们所删除的乃是另外一个obj对象呢(在此处是会出现报错情况的), 其缘由在于path的那些子节点并非是我们新近创建出的这个obj。
三、保存xml文件
于我们已然完成修改的xml来讲, 上述进行了属性的更改, 增添了子节点, 移除了字节点, 将操作之后的tree保存为新的xml文件, 采用。
importxml.etree.ElementTree as ET file_xml='/home/g4/桌面/project/安全帽100/99.xml'tree= ET.parse(file_xml)#读取treeroot =tree.getroot() path= root.find('path') obj= root.find('object') path.append(obj)#在path子节点下增加一个子节点root.remove(obj)#在root节点下删除一个子节点new_tree = ET.ElementTree(root)#root为修改后的rootnew_tree.write("test.xml", encoding='utf-8') # 保存为xml文件
最主要的保存操作, 是位置处于最后的那两行, 在这里, 因为存在着中文这种情况, 所以传入的参数等于‘utf - 8’这一表述了。
看看最后结果。