【医学影像数据处理】 XML 文件格式处理汇总

xml(Extensible Markup Language,简称:XML)可扩展标记语言,是一种netconf配置文件的格式。是一种固有的分层数据格式,最自然的表示方式是解析成树状。 但是,xml这样的标签数据,是面向"机器"识别的,是不利于"人类"识别的,所以看起来会比较的麻烦。

2003年5月成立了Netconf工作组,该工作组主要是为了提出一个全新的基于XML的网络配置(NETCONF)协议而成立的。

Python内置的API:xml.etree.ElementTree 可以解析xml文件。ElementTree将整个xml文档解析成树状结构, Element就表示这个树状结构中的单节点。

官方文件地址:The ElementTree XML API

后面举例以下面这个xml的文件形式展开,这也是官方给出的一个案例。xml文档实例如下:

xml文档实例如下:

xml 复制代码
<?xml version="1.0"?>
<data id="world country">
    <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>

一、xml 数据格式

Element常用属性对应的xml格式,如下:

xml 复制代码
<tag attrib="netmiko_inventory">text</tag>

例:

xml 复制代码
<device_type desc="platform">cisco_ios</device_type>
    tag       attrib         text       tag

其中:

1、 tag:是str对象,表示xml标签,例子中的前后闭合的device_type

2、 attrib:是一个dict对象,表示xml属性,例子中的desc="platform"

3、 text:是xml数据标签包裹的内容,也是Element的内容,例子中的 cisco_ios

4、 child elements:则是xml一对标签中包含的子集,如下图,类似于country 标签中包裹的内容

举例:

python 复制代码
import xml.etree.ElementTree as ET

# 读取、解析文件,获取跟元素
tree = ET.parse('sample.xml')
root = tree.getroot()

# 获取根元素的标签名称以及所有属性
# data
print('root.tag:', root.tag)
print('root.attrib:', root.attrib)

# 获取text
print(root[0][1].text)

输出结果:

复制代码
root.tag: data
root.attrib: {'id': 'world country'}
2008

二、查找方法

Element有很丰富的查找方法,总结如下:

  • iter(tag=None): 遍历Elementchild,可以指定tag精确查找;
  • findall(match) :查找当前元素tagpath能匹配的child节点;
  • find(match) :查找当前元素tagpath能匹配的第一个child节点;
  • get(key, default=None) :获取元素指定key对应的attrib,如果没有attrib,返回default
python 复制代码
# 一次性获取所有名为 country 的元素、然后遍历
for country in root.findall('country'):
    # 获取 country 元素中的 name 属性
    name = country.get('name')

    # 寻找名为 rank 的子节点,获取其text
    rank = country.find('rank').text

    # 一次性获取所有名为 country 下 neighbor的元素、然后遍历
    neighbors = country.findall('neighbor')

    neighbor_name = []
    for neighbor in neighbors:
        n = neighbor.get('name')
        neighbor_name.append(n)
    print(name, rank, neighbor_name)

打印结果如下:

复制代码
Liechtenstein 1 ['Austria', 'Switzerland']
Singapore 4 ['Malaysia']
Panama 68 ['Costa Rica', 'Colombia']

三、iter迭代器

Element使用iter迭代器可以递归地遍历它下面的所有child

python 复制代码
# 一次性获取所有名为 country 的元素、然后遍历
for country in root.iter('country'):
    # 获取 country 元素中的 name 属性
    name = country.get('name')
    print(name)

for rank in root.iter('rank'):
    # 获取 country 元素中的 name 属性
    rank_n = rank.text
    print(rank_n)

打印结果如下:

复制代码
Liechtenstein
Singapore
Panama

1
4
68

四、xml数据转换成字典

xmltodict使用非常的简单,学习成本很低,可以快速的把xml格式的数据转换成字典,轻松进行数据二次加工。

代码如下:

python 复制代码
import xmltodict, json

with open('sample.xml') as f:
    my_dict = xmltodict.parse(f.read())
    
with open('info1.json', 'w') as f:
    json.dump(my_dict, f, sort_keys=False, indent=2)

打开info1.json查看,保存的内容如下:

dict 复制代码
{
  "data": {
    "@id": "world country",
    "country": [
      {
        "@name": "Liechtenstein",
        "rank": "1",
        "year": "2008",
        "gdppc": "141100",
        "neighbor": [
          {
            "@name": "Austria",
            "@direction": "E"
          },
          {
            "@name": "Switzerland",
            "@direction": "W"
          }
        ]
      },
      {
        "@name": "Singapore",
        "rank": "4",
        "year": "2011",
        "gdppc": "59900",
        "neighbor": {
          "@name": "Malaysia",
          "@direction": "N"
        }
      },
      {
        "@name": "Panama",
        "rank": "68",
        "year": "2011",
        "gdppc": "13600",
        "neighbor": [
          {
            "@name": "Costa Rica",
            "@direction": "W"
          },
          {
            "@name": "Colombia",
            "@direction": "E"
          }
        ]
      }
    ]
  }
}

其中:

  • tagattrib都会变成字典的key,例如,上面的data、id、country、name、rank等等;
  • 但是,带有属性attribkey,会自动加入@符号,其他不会;
  • key对应的value,会变成字符串形式。

五、保存成xml

xmltodict不仅可以将xml转为字典形式,还可以将字典转成xml形式,存储到本地,如下所示:

python 复制代码
def saveXML():
    import xmltodict

    with open('info.xml', 'w') as f:
           info_dict = {
                   'dev_info': {
                           'device_type': 'cisco_ios',
                           'username': 'admin',
                           'password': 'cisco',
                           'ip': '192.168.47.10'
                  }
          }
           f.write(xmltodict.unparse(info_dict, pretty=True))

保存为xml文件后,打开查看结果如下:

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<dev_info>
	<device_type>cisco_ios</device_type>
	<username>admin</username>
	<password>cisco</password>
	<ip>192.168.47.10</ip>
</dev_info>

六、总结

前面对xml文件做了简单的学习,包括什么是xml,以及在python中怎么读取、操作和存储为xml文件。同时将机器友好的xml文件,转成对人友好的字典查看。xml确实不太好查看和解析,弄起来有些费劲啊。

相关推荐
前网易架构师-高司机4 天前
带标注的扑克牌识别数据集,识别率99.5%,3083张图,支持yolo,coco json,voc xml,文末有模型训练代码
xml·yolo·json·数据集·数字·扑克牌·纸牌
执明wa4 天前
LayoutInflater详解: XML是如何变成View的?
android·xml·开发语言·android studio
IT_Octopus7 天前
一次由 RestTemplate 引发的 Connection reset:被 XML 截胡的请求体
xml·java·spring boot
Dontla7 天前
网站爬虫控制策略介绍(robots.txt、sitemap.xml、x-robots-tag、noindex、nofollow)网站索引
xml·爬虫·dubbo
风起洛阳@不良使8 天前
spring中xml和注解开发的对比
xml·java·spring
Mikowoo0079 天前
批量汇总XML格式的发票信息
xml·python
逃逸线LOF9 天前
xml文件如何加载properties文件(spring容器加载properties文件)
xml
前网易架构师-高司机12 天前
带标注的山体滑坡塌方数据集数据集,识别率78.1%,974张图,支持yolo,coco json,voc xml,文末有模型训练代码
xml·yolo·json·数据集·自然灾害·山体滑坡
程序媛kelly12 天前
.xml / .jrxml 文件怎么打开?OpenFiles 实测预览、编辑、搜索与 AI 摘要排查流程
xml·人工智能·jrxml
潘潘的嵌入式日记12 天前
改完Keil工程文件被缓存覆盖?——uvprojx编辑的进阶四坑
xml·嵌入式·keil·调试·mdk·工程文件