Python学习之操作XML文件详解

news2024/12/27 0:59:54

概要

我们经常需要解析用不同语言编写的数据,Python 提供了许多第三方库来解析或拆分用其他语言编写的数据,今天我们来学习下 Python XML 解析器的相关功能。


什么是 XML?

XML 是可扩展标记语言,它在外观上类似于 HTML,但 XML 用于数据表示,而 HTML 用于定义正在使用的数据。XML 专门设计用于在客户端和服务器之间来回发送和接收数据。看看下面的例子:

<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<food>
    <item name="breakfast">Idly</item>
    <price>$2.5</price>
    <description>
   Two idly's with chutney
   </description>
    <calories>553</calories>
</food>
<food>
    <item name="breakfast">Paper Dosa</item>
    <price>$2.7</price>
    <description>
    Plain paper dosa with chutney
    </description>
    <calories>700</calories>
</food>
<food>
    <item name="breakfast">Upma</item>
    <price>$3.65</price>
    <description>
    Rava upma with bajji
    </description>
    <calories>600</calories>
</food>
<food>
    <item name="breakfast">Bisi Bele Bath</item>
    <price>$4.50</price>
    <description>
   Bisi Bele Bath with sev
    </description>
    <calories>400</calories>
</food>
<food>
    <item name="breakfast">Kesari Bath</item>
    <price>$1.95</price>
    <description>
    Sweet rava with saffron
    </description>
    <calories>950</calories>
</food>
</metadata>

上面的示例显示了命名为“Sample.xml”的文件的内容,后面的代码示例都会基于此 XML 例子来进行。

Python XML 解析模块

Python 允许使用两个模块解析这些 XML 文档,即 xml.etree.ElementTree 模块和 Minidom(最小 DOM 实现)。解析意味着从文件中读取信息,并通过识别特定 XML 文件的各个部分将其拆分为多个片段。让我们进一步了解如何使用这些模块来解析 XML 数据。

xml.etree.ElementTree 模块:

该模块帮助我们将 XML 数据格式化为树结构,这是分层数据的最自然表示。元素类型允许在内存中存储分层数据结构,并具有以下属性:

PropertyDescription
Tag一个字符串,表示正在存储的数据类型
Attributes由存储为字典的许多属性组成
Text String包含需要显示的信息的文本字符串
Tail String如有必要,也可以有尾弦
Child Elements由许多存储为序列的子元素组成

ElementTree 是一个封装元素结构并允许与 XML 相互转换的类,现在让我们尝试使用 python 模块解析上述 XML 文件。

有两种方法可以使用ElementTree模块解析文件。

第一个是使用 parse() 函数,第二个是 fromstring() 函数。parse() 函数解析作为文件提供的 XML 文档,而 fromstring 在作为字符串提供时解析 XML,即在三引号内。

使用 parse() 函数:

如前所述,该函数采用文件格式的 XML 进行解析,看看下面的例子:

import xml.etree.ElementTree as ET
mytree = ET.parse('sample.xml')
myroot = mytree.getroot()

我们需要做的第一件事是导入 xml.etree.ElementTree 模块,然后使用 parse() 方法解析“Sample.xml”文件,getroot() 方法返回“Sample.xml”的根元素。

当执行上述代码时,我们不会看到返回的输出,但只要不会有错误就表明代码已成功执行。要检查根元素,可以简单地使用 print 语句,如下所示:

import xml.etree.ElementTree as ET
mytree = ET.parse('sample.xml')
myroot = mytree.getroot()
print(myroot)

Output:

<Element ‘metadata’ at 0x033589F0>

上面的输出表明我们的 XML 文档中的根元素是“元数据”。

使用 fromstring() 函数

我们还可以使用 fromstring() 函数来解析字符串数据,我们需要将 XML 作为三引号内的字符串传递,如下所示:

import xml.etree.ElementTree as ET
data='''<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<food>
    <item name="breakfast">Idly</item>
    <price>$2.5</price>
    <description>
   Two idly's with chutney
   </description>
    <calories>553</calories>
</food>
</metadata>
'''
myroot = ET.fromstring(data)
#print(myroot)
print(myroot.tag)

上面的代码将返回与前一个相同的输出,用作字符串的 XML 文档只是“Sample.xml”的一部分,已将其用于提高可见性,也可以使用完整的 XML 文档。

还可以使用“标签”对象检索根标签,如下所示:

print(myroot.tag)

Output:

metadata

还可以通过仅指定要在输出中看到的字符串部分来对标记字符串输出进行切片。

print(myroot.tag[0:4])

Output:

meta

如前所述,标签也可以具有字典属性。要检查根标签是否有任何属性,您可以使用“attrib”对象,如下所示:

print(myroot.attrib)

Output:

{}

可以看到,输出是一个空字典,因为我们的根标签没有属性。

寻找感兴趣的元素

根也由子标签组成,要检索根标签的子标签,可以使用以下命令:

print(myroot[0].tag)

Output:

food

现在,如果要检索根的所有第一个子标记,可以使用 for 循环对其进行迭代,如下所示:

for x in myroot[0]:
     print(x.tag, x.attrib)

Output:

item {‘name’: ‘breakfast’}
price {}
description {}
calories {}

返回的所有项目都是食物的子属性和标签。

要使用 ElementTree 从 XML 中分离出文本,可以使用 text 属性。例如,如果想检索关于第一个食物的所有信息,应该使用以下代码:

for x in myroot[0]:
        print(x.text)

Output:

Idly
$2.5
Two idly’s with chutney
553

可以看出,第一项的文本信息已作为输出返回。现在如果想以特定价格显示所有商品,可以使用 get() 方法,此方法访问元素的属性。

for x in myroot.findall('food'):
    item =x.find('item').text
    price = x.find('price').text
    print(item, price)

Output:

Idly $2.5
Paper Dosa $2.7
Upma $3.65
Bisi Bele Bath $4.50
Kesari Bath $1.95

上面的输出显示了所有必需的项目以及每个项目的价格,使用 ElementTree,还可以修改 XML 文件。

修改 XML 文件

我们的 XML 文件中的元素是可以被操纵的,为此,可以使用 set() 函数。让我们先来看看如何在 XML 中添加一些东西。

添加到 XML:

以下示例显示了如何在项目描述中添加内容。

for description in myroot.iter('description'):
     new_desc = str(description.text)+'wil be served'
     description.text = str(new_desc)
     description.set('updated', 'yes')
 
mytree.write('new.xml')

write() 函数有助于创建一个新的 xml 文件并将更新的输出写入该文件,但是也可以使用相同的功能修改原始文件。执行上述代码后,将能够看到已创建一个包含更新结果的新文件。

要添加新的子标签,可以使用 SubElement() 方法。例如,如果想在第一项 Idly 中添加新的专业标签,可以执行以下操作:

ET.SubElement(myroot[0], 'speciality')
for x in myroot.iter('speciality'):
     new_desc = 'South Indian Special'
     x.text = str(new_desc)
 
mytree.write('output5.xml')

就像我们所见到的,在第一个食物标签下添加了一个新标签。可以通过在 [] 括号内指定下标来在任意位置添加标签。

下面让我们看看如何使用这个模块删除项目。

从 XML 中删除:

要使用 ElementTree 删除属性或子元素,可以使用 pop() 方法,此方法将删除用户不需要的所需属性或元素。

myroot[0][0].attrib.pop('name', None)
 
# create a new XML file with the results
mytree.write('output5.xml')

Output:

cfac6e9c819e4d6eaeac5bb6b87933ea.jpg 上图显示 name 属性已从 item 标记中删除。要删除完整的标签,可以使用相同的 pop() 方法,如下所示:

myroot[0].remove(myroot[0][0])
mytree.write('output6.xml')

Output:

c6d49b3582fd4f12af7b9c3bdb4bbdb6.jpg

 输出显示食品标签的第一个子元素已被删除。如果要删除所有标签,可以使用 clear() 函数,如下所示:

myroot[0].clear()
mytree.write('output7.xml')

执行上述代码时,food 标签的第一个子标签将被完全删除,包括所有子标签。

到目前为止,我们一直在使用 Python XML 解析器中的 xml.etree.ElementTree 模块。现在让我们看看如何使用 Minidom 解析 XML。

xml.dom.minidom Module

该模块基本上是由精通DOM(文档对象模块)的人使用的,DOM 应用程序通常首先将 XML 解析为 DOM。在 xml.dom.minidom 中,可以通过以下方式实现

使用 parse() 函数:

第一种方法是通过提供要解析的 XML 文件作为参数来使用 parse()函数。例如:

from xml.dom import minidom
p1 = minidom.parse("sample.xml")

执行此操作后,将能够拆分 XML 文件并获取所需的数据。还可以使用此函数解析打开的文件。

dat=open('sample.xml')
p2=minidom.parse(dat)

在这种情况下,存储打开文件的变量作为参数提供给 parse 函数。

使用 parseString() 方法:

当我们想要提供要作为字符串解析的 XML 时使用此方法。

p3 = minidom.parseString('<myxml>Using<empty/> parseString</myxml>')

可以使用上述任何方法解析 XML,现在让我们尝试使用这个模块获取数据

寻找感兴趣的元素

在我的文件被解析后,如果我们尝试打印它,返回的输出会显示一条消息,即存储解析数据的变量是 DOM 的对象。

dat=minidom.parse('sample.xml')
print(dat)

Output:

<xml.dom.minidom.Document object at 0x03B5A308>

使用 GetElementsByTagName 访问元素

tagname= dat.getElementsByTagName('item')[0]
print(tagname)

如果我们尝试使用 GetElementByTagName 方法获取第一个元素,我将看到以下输出:

<DOM Element: item at 0xc6bd00>

请注意,只返回了一个输出,因为为方便起见,这里使用了 [0] 下标,这将在进一步的示例中被删除。

要访问属性的值,我们将不得不使用 value 属性,如下所示:

dat = minidom.parse('sample.xml')
tagname= dat.getElementsByTagName('item')
print(tagname[0].attributes['name'].value)

Output:

breakfast

要检索这些标签中存在的数据,可以使用 data 属性,如下所示:

print(tagname[1].firstChild.data)

Output:

Paper Dosa

还可以使用 value 属性拆分和检索属性的值。

print(items[1].attributes['name'].value)

Output:

breakfast

要打印出我们菜单中的所有可用项目,可以遍历这些项目并返回所有项目。

for x in items:
    print(x.firstChild.data)

Output:

Idly
Paper Dosa
Upma
Bisi Bele Bath
Kesari Bath

要计算我们菜单上的项目数,可以使用 len() 函数,如下所示:

print(len(items))

Output:

5

输出指定我们的菜单包含 5 个项目。

 

今天的分享就到这里,喜欢的朋友可以点赞收藏转发,感谢🙏 

---END---

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/898990.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

all in one之安装zerotier(第四章)

好像zerotier国内ipv4不能使用 pve安装zerotier 内网穿透软件总结参考 安装参考教程 安装命令&#xff1a; curl -s https://install.zerotier.com | sudo bash官网 如果有以下问题&#xff0c;进行解决&#xff0c;如果没有则跳过。 问题&#xff1a;-bash: sudo: comman…

每天一道leetcode:127. 单词接龙(图论困难建图广度优先遍历)

今日份题目&#xff1a; 字典 wordList 中从单词 beginWord 和 endWord 的 转换序列 是一个按下述规格形成的序列 beginWord -> s1 -> s2 -> ... -> sk&#xff1a; 每一对相邻的单词只差一个字母。 对于 1 < i < k 时&#xff0c;每个 si 都在 wordList 中…

2023全网Mysql 合集(25w字)附课程 从安装到高级,实战

mysql学习 1.安装mysql 安装教程 2.mysql的详细学习教程 mysql的详细教程 3.mysql 的高级优化 MySQL高级篇&#xff08;SQL优化、索引优化、锁机制、主从复制&#xff09; 4.MySQL 面试 MySQL数据库面试题总结 二.mysql实战 一、创建数据表并插入数据 1、学生表 Stud…

【python办公自动化】PysimpleGUI中的popup弹窗中的按钮设置居中

PysimpleGUI中的popup弹窗中的按钮设置居中 背景问题解决背景 默认的popup弹窗中的OK按钮是在最下面偏左侧一些,有时需要将按钮放置居中 问题解决 首先找到pysimplegui源代码文件中popup的部分 然后定位到19388行,源文件内容如下 关于popup弹窗OK按钮的设置,将pad属性…

C语言好题解析(三)

目录 选择题一选择题二选择题三选择题四编程题一编程题二 选择题一 以下程序段的输出结果是&#xff08;&#xff09;#include<stdio.h> int main() { char s[] "\\123456\123456\t"; printf("%d\n", strlen(s)); return 0; }A: 12 B: 13 …

《算法竞赛·快冲300题》每日一题:“糖果配对”

《算法竞赛快冲300题》将于2024年出版&#xff0c;是《算法竞赛》的辅助练习册。 所有题目放在自建的OJ New Online Judge。 用C/C、Java、Python三种语言给出代码&#xff0c;以中低档题为主&#xff0c;适合入门、进阶。 文章目录 题目描述题解C代码Java代码Python代码 “ 糖…

使用自己的领域数据扩充baichuan模型词表(其他模型也一样)

文章目录 前言环境项目结构一、使用步骤二、训练词表三、合并词表四、效果前言 总的来说,扩充词表可以加快解码速度,对于对中文支持不太友好的模型(如llama),扩充词表还能提升模型在中文的表现。 环境 jsonlines==3.1.0 sentencepiece==0.1.99 transformers==4.28.1项目…

【Golang系统开发】搜索引擎(3) 压缩倒排索引表

写在前面 假设我们的数据集中有 800000 篇文章&#xff0c;每篇文章有 200 词条&#xff0c;每个词条有6个字符&#xff0c;倒排记录数目是 1 亿。那么如果我们倒排索引表中单单记录文档id&#xff0c;不记录文档内的频率和偏移信息。 那么 文档id 的长度就必须是 l o g 2 8…

04.Show, Attend and Tell

目录 前言泛读摘要IntroductionRelated Work小结 精读编码器&#xff1a;特征卷积解码器&#xff1a;LSTM网络随机硬注意力和确定软注意力机制硬注意力软注意力双重随机注意力 训练实验数据集评估过程定量分析定性分析 结论 代码&#xff08;略&#xff09; 前言 本课程来自深…

前端单点登录SSO面试回答

JWT鉴权机制 1.JWT用于登录身份验证 2.用户登录成功后&#xff0c;后端通过JWT机制生成一个token&#xff0c;返回给客户端 3.客户端后续的每次请求都需要携带token&#xff0c;放在header的authorization中 4.后端从authorization中拿到token后&#xff0c;通过secretKey进…

密码学学习笔记(二十):DSA签名与X.509证书

数字签名 下图是一个制作以及使用数字签名过程的通用模型。 假设Bob发送一条消息给Alice&#xff0c;尽管消息并不重要&#xff0c;也不需要保密&#xff0c;但他想让Alice知道消息确实是他本人发的。出于这个目的&#xff0c;Bob利用一个安全的散列函数&#xff0c;比如SHA-…

elaticsearch(1)

1.简介 Elasticsearch是一个开源的高扩展的分布式全文检索引擎&#xff0c;它可以近乎实时的存储、检索数据&#xff1b;本身扩展性很好&#xff0c;可以扩展到上百台服务器&#xff0c;处理PB级别的数据。 Elasticsearch也使用Java开发并使用Lucene作为其核心来实现所有索引…

【C++ 记忆站】引用

文章目录 一、引用概念二、引用特性1、引用在定义时必须初始化2、一个变量可以有多个引用3、引用一旦引用一个实体&#xff0c;再不能引用其他实体 三、常引用四、使用场景1、做参数1、输出型参数2、大对象传参 2、做返回值1、传值返回2、传引用返回 五、传值、传引用效率比较六…

电脑提示msvcp140.dll丢失的解决方法,dll组件怎么处理

Windows系统有时在打开游戏或者软件时&#xff0c; 系统会弹窗提示缺少“msvcp140.dll.dll”文件 或者类似错误提示怎么办&#xff1f; 错误背景&#xff1a; msvcp140.dll是Microsoft Visual C Redistributable Package中的一个动态链接库文件&#xff0c;它在运行软件时提…

Scratch 之 算法教程 -- 递归

递归是指物体表现出相似的重复性。它在生活中很常见&#xff0c;如俄罗斯套娃、汉诺塔游戏、分形图案&#xff08;科赫雪花、谢尔宾斯三角形等&#xff09;、两个面对面的镜子、斐波那契数列&#xff0c;二叉树等 在计算机科学中&#xff0c;递归是指函数定义中重复调用自己的行…

【高频面试题】 消息中间件

文章目录 1、RabbitMQ1.1 RabbitMQ-如何保证消息不丢失1.2 RabbitMQ消息的重复消费问题如何解决的1.3 RabbitMQ中死信交换机 ? (RabbitMQ延迟队列有了解过嘛)1.4 RabbitMQ如果有100万消息堆积在MQ , 如何解决(消息堆积怎么解决)1.5 RabbitMQ的高可用机制有了解过嘛 2、Kafka2.…

【数据结构OJ题】有效的括号

原题链接&#xff1a;https://leetcode.cn/problems/valid-parentheses/ 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 这道题目主要考查了栈的特性&#xff1a; 题目的意思主要是要做到3点匹配&#xff1a;类型、顺序、数量。 题目给的例子是比较…

实现数字化成功:5R模式如何支持车企数字化营销

01 车企进入“大逃杀”时间 汽车行业一边是出口“捷报频传”&#xff0c;一边是内销“压力山大”。 内销的难&#xff0c;在之前中部某省的政府“骨折价”补贴掀起的“价格战”中已经可见一斑。这一颇具标志性的事件反映了汽车行业&#xff0c;尤其是燃油车行业正处在巨大的转…

uni-app 经验分享,从入门到离职(二)—— tabBar 底部导航栏实战篇

文章目录 &#x1f4cb;前言⏬关于专栏 &#x1f3af;关于小程序 tabbar 的一些知识&#x1f3af;创建一个基本的 tabBar&#x1f4dd;最后 &#x1f4cb;前言 这篇文章的内容主题是关于小程序的 tabBar 底部导航栏的入门使用和实战技巧。通过上一篇文章的基础&#xff0c;我们…

学习笔记230801--vue项目图片绝对路径和相对路径引入编译加载问题

问题描述&#xff1a; 在组件中引入图片出现了问题,<img>标签的src属性&#xff0c;动态绑定import引入的绝对路径图片或者直接在src静态引入图片绝对路径都可以在页面渲染出来&#xff0c;在浏览器可以看到路径都转成了dataUrl&#xff0c;但是动态绑定图片的绝对路径却…