使用 Python 解析 XML —— 终极指南 2024

一、导言

标准是明确和界定世界上人与人、人与物之间交流的一种手段。例如,人类语言、计算机 USB 插座或倒牛奶前必须先加麦片的事实。说到计算机应用程序和系统,有一种标准是最受开发人员欢迎的,它就是 XML(可扩展标记语言)。在本文中,我们将探讨如何使用 Python 的内置库从 XML 文件中解析数据,了解解析的最佳方法,并理解有效读取信息的重要性。

二、什么是 XML?

XML(可扩展标记语言)是一种标记语言,用于许多旨在存储和传输数据的应用程序中。它是创建结构化文档以及在网络上不同系统和应用程序之间交换数据的标准。XML 文件使用标记来定义文档中的元素,类似于 HTML(超文本标记语言)。不过,HTML 是为了显示数据而设计的,而 XML 则是为了在各种应用程序中存储和交互使用数据而设计的。

获取更多信息或购买代理,请访问 Smartdaili。

1.XML 示例

让我们来看一个 XML 文件示例:

<?xml version="1.0" encoding="UTF-8"?>
<animal>
  <item>
    <name>cat</name>
    <description> Cats are small, carnivorous mammals that are often kept as pets. Known for their agility, flexibility, and independent nature, cats make delightful companions.</description>
    <breeds>
      <breed>Persian</breed>
      <breed>Siamese</breed>
      <breed>Maine Coon</breed>
      <breed>Bengal</breed>
      <breed>Ragdoll</breed>
    </breeds>
  </item>
</animal>

在这里,你可以看到许多元素在文档内容中是按层次组织和结构的。在本例中,这些元素如下:

XML 声明 - 简要介绍 XML 文档、版本和编码;
《animal》 是根元素;
《item》 代表动物的一个实例,特别是一只猫;
《name》 包含动物的名称,即 “猫”;
《description》 是对 "猫 "的简短描述;
《breeds》 是一个容器,用于使用 元素列出不同的猫品种。

这些列表便于人类和计算机阅读和理解。这就是为什么它们在不同系统之间存储和交换数据时如此受欢迎——它不会让事情变得过于复杂,可以完全自由地以任何方式创建有组织的项目列表。

三、 如何用 Python 解析 XML?

Python 提供了几种解析 XML 文件的内置方法,因此您不必急于安装任何外部库。这些方法是 xml.dom.minidomxml.etree.ElementTree 模块以及 XPath 表达式。让我们逐一详细了解一下。

xml.dom.minidom 是 Python 标准库中的一个模块,它为处理 XML 文档提供了文档对象模型 (DOM) 的最小实现。DOM 以对象树的形式表示 XML 文档的结构,使通过代码管理、遍历和修改 XML 文件内容变得简单。它提供了文档的完整表示形式,让您可以快速操作和查看 XML 数据。虽然这是一种非常方便的方法,但这种方法需要大量内存,对于大型 XML 文档来说可能并不高效。

xml.etree.ElementTree 提供了一种略有不同的方法来解析和处理 XML 文档。该模块基于 ElementTree API,后者更轻量级、更高效,旨在方便日常的 XML 文件处理任务。它将 XML 文档表示为一棵由 Element 对象组成的树。每个 Element 对象代表文档中的一个 XML 元素,它可以有子元素、属性和文本内容。虽然它缺乏完整 DOM 的某些功能,但通常速度更快,内存占用更少,因此适合大型文档。

XPath 是另一种用于浏览 XML 文件的方法。虽然它不是一个 Python 库,但它是一种解析 XML 文件的通用方法,可用于许多其他编程语言,如 JavaScript、Java、C 或 C++。你甚至可以用它来使用 Google Sheets 搜刮网页!它通过编写从根元素到所需目标节点的路径来构建表达式,详细说明了如何到达 XML 元素。这并不是最简单的方法,但却非常有用。

以上只是用 Python 解析 XML 文件的几种方法。虽然还有许多其他方法,但 Python 编码语言因其轻量级、易于使用的模块和简单的实现而成为一种方便、简单的工具。在下面的章节中,我们将更详细地探讨 xml.etree.ElementTree 模块和 XPath expression 语言,并了解如何将它们与实际数据一起使用,从 XML 文件中提取有价值的数据。

四、使用 ElementTree 解析 XML 文档

让我们从 Python 的 xml.etree.ElementTree 模块开始。由于 XML 文件中的数据是分层结构的,因此将其表示为由相互分支的元素组成的树是最合理的。为此,该模块有两个类:ElementTree 将整个 XML 文档表示为一棵树,而 Element 则是树中的一个节点。把它想象成一棵真正的树–它从根部开始,以多种方式分支,但每个分支的末端都有一个苹果。你需要像一只灵活的松鼠一样在树枝间穿梭,才能品尝到多汁的 XML 数据果实。

获取更多信息或购买代理,请访问 Smartdaili。

1. 使用元素树

在本例中,我们将使用以下 XML 文件:

<?xml version="1.0" encoding="UTF-8"?>
<pets>
  <cat>
    <name>Jinx</name>
    <age>2</age>
    <color>Gray</color>
    <breed>Maine Coon</breed>
  </cat>
  <cat>
    <name>Kafka</name>
    <age>3</age>
    <color>White</color>
    <breed>Siamese</breed>
  </cat>
  <cat>
    <name>Mori</name>
    <age>1</age>
    <color>Orange</color>
    <breed>Tabby</breed>
  </cat>
</pets>

首先,创建一个 Python 脚本文件并导入 xml.etree.ElementTree 库。它通常用 ET 别名来缩写。

import xml.etree.ElementTree as ET

接下来,从 XML 文件导入数据。您可以直接将 XML 文件字符串粘贴到代码中并进行解析。注意在将 XML 文件字符串赋值给变量时,其两侧都使用了三引号(“”“”):

import xml.etree.ElementTree as ET
xml = """<?xml version="1.0" encoding="UTF-8"?>
<pets>
  <cat>
    <name>Jinx</name>
    <age>2</age>
    <color>Gray</color>
    <breed>Maine Coon</breed>
  </cat>
  <cat>
    <name>Kafka</name>
    <age>3</age>
    <color>White</color>
    <breed>Siamese</breed>
  </cat>
  <cat>
    <name>Mori</name>
    <age>1</age>
    <color>Orange</color>
    <breed>Tabby</breed>
  </cat>
</pets>
"""
root_element = ET.fromstring(xml)
print(root_element)

另外,更好的做法是将 XML 保存在一个单独的文件中。命名为 data.xml。然后就可以像这样解析其中的信息了:

import xml.etree.ElementTree as ET
tree = ET.parse("data.xml")
root_element = tree.getroot()
print(root_element)

这两个代码示例都将返回相同的结果–XML 树的根元素。您可以浏览整个树,从这里获取所需的

五、导航 XML 树

按照我们的代码示例,我们提取了 XML 文件的根元素。每个节点都是根元素 pets 的后代。记住这一点,你就可以通过子元素迭代或索引来指定要获取的节点,从而轻松浏览树状结构。

1. 循环方法

您需要编写一个循环,通过搜索子元素来浏览树:

for child in root_element:
print(child.tag)

脚本将只打印 《pets》 标记的直接子元素,因此只打印了几个 《cat》 标记。要进一步遍历,需要遍历每个 《cat》 并打印文本信息:

for child in root_element:
    for desc in child:
        print(desc.text)

2. 索引法

虽然循环方法有助于打印尽可能多的信息,但编写如此多的嵌套循环可能会很麻烦。为了更快地找到特定节点,可以使用索引指向元素所在的位置。例如,我们来获取第一只猫的颜色。如果你简单看一下我们的 XML,就可以根据每个节点与其父元素的相关位置为其分配一个编号:

...
<pets> #0
  <cat> #0
    <name>Jinx</name> #0
    <age>2</age> #1
    <color>Gray</color> #2 (the element you want to get)
    <breed>Maine Coon</breed> #3
  </cat>
...

Python 是一种以 0 为基础的语言,因此您需要记住从 0 开始计数,而不是从 1 开始。由于您想获得第一只猫,因此第一个索引写为 0。接下来,您需要查看哪个节点是 《color》 标记 - 它是 《cat》 下的第 3 个节点;因此,指定索引为 2。

cat_info = root_element[0][2].text
print(cat_info)

3. 其他方法

元素类还有其他几个有价值的方法,可以获取所需的信息。其中一个是 Element.iter(),它可以遍历下面的每个节点。您甚至可以指定要打印的元素。例如,让我们通过指定 *"age "*来获取每只猫的年龄信息:

for age in root_element.iter("age"):
    print(age.text)

Element.find() 将查找带有特定标记的节点的第一个子节点。Element.findall() 将查找当前节点的所有直接子元素节点:

for animal in root_element.findall("cat"): # Loop and find all direct child elements of <pets>, which are <cat>
    name = animal.find("name").text # Find the first <name> element under a particular <cat>
    print(name) # Print the name

使用这些方法中的任何一种,你都可以创建一个精确的脚本来导航到 XML 文件中的某条信息。在实际应用中,XML 文件可能比这里的示例复杂得多,您需要编写更长的循环、动态索引,并利用各种元素类方法。

六、从 XML 中提取数据

要从 XML 文件中提取数据,请使用上述示例之一来浏览 XML 文件,并只获取所需的 XML 数据。下一步完全取决于你要做什么–可能只需将信息打印到终端,或者保存到 CSV 文件供以后使用和分析。
要将信息打印到终端或类似的命令行工具,只需像之前一样使用 print() 函数即可。
将信息保存到 CSV 文件则需要多花点功夫。你需要导入 csv 库,将 XML 数据写入文件。在这里,脚本将只获取每只猫的名字和年龄,并将这些信息保存到 CSV 文件中。如果不确定每一行的作用,请按照代码中的注释进行操作:

获取更多信息或购买代理,请访问 Smartdaili。

import xml.etree.ElementTree as ET
import csv # Import the CSV library

import xml.etree.ElementTree as ET
tree = ET.parse("data.xml")
root_element = tree.getroot()

with open("cats_data.csv", 'w', newline='') as csvfile: # Open the CSV file to write in
    csv_writer = csv.writer(csvfile) # Create a new CSV writer object
    csv_writer.writerow(['Name', 'Age']) # Write the header information
    for cat in root_element.findall('cat'): # Iterate through all cat elements in the XML
        name = cat.find('name').text # Extract the name
        age = cat.find('age').text # Extract the age
        csv_writer.writerow([name, age]) # Write the information into the CSV file
        
print(f"Data saved to CSV file.")

运行脚本后,你会看到 cats_data.csv 文件出现在与脚本文件相同的目录下。如果检查该文件,就会发现它与 XML 文件中的数据一致:

Name,Age
Jinx,2
Kafka,3
Mori,1

就是这样!这些数据可用于其他工具和应用程序的进一步分析。无论 XML 文件中添加了多少额外数据,该脚本都会打印出每只猫的名字和年龄,并导出为 CSV 格式。

七、使用 Xpath 解析 XML 文档

XPath(XML 路径语言)是一种查询语言,用于从 XML 文档中选择节点。它通过指定元素和属性的位置,提供了一种导航和查询 XML 数据层次结构的方法。XPath 使用路径符号(类似于文件系统中的文件路径)来遍历 XML 文档树并获取特定节点。
XPath 是一种充满活力的表达式语言,拥有 200 多个函数,可用于从简单到复杂的各种用途。要更深入地了解 XPath 的所有可能方法和使用方式,请查看 W3Schools 教程或参阅 devhints.io cheatsheet

1. 使用 XPath

要使用 XPath,我们将继续使用 Python xml.etree.ElementTree library。这是因为 Python 本身无法读取或理解 XPath 查询。Element 类有一个我们已经简单探讨过的方法 - Element.findall()。要编写 XPath 查询,只需使用该方法及其中的路径即可。

2. 使用 XPath 搜索 XML

我们将使用与之前相同的 XML 数据,如果还没有复制并保存上面的 XML 文件,请复制并保存。让我们从一个熟悉的例子开始–查找 XML 文件树的根元素。首先导入 xml.etree.ElementTree 库,然后从 data.xml 文件中获取 XML 数据。

import xml.etree.ElementTree as ET

tree = ET.parse("data.xml")
root_element = tree.getroot()

下一步是使用 Element.findall() 方法并向其传递". "字符串。这是选择当前节点的 XPath 语法。由于您还没有导航到任何地方,因此当前节点将始终是树的根节点。下面是代码中的样子:

root = root_element.findall(".")
print(root)

以上就是使用 Python 的 XPath 查询从 XML 文件中获取数据的基础知识。您还可以使用 lxmllibxml2 等库,它们也能为您完成同样的工作。请阅读它们的专用文档,了解更多有关将它们与 Python 结合使用来解析 XML 文件的信息。

3. 使用 XPath 解析 XML

要获取更具体的数据,XPath 就会变得稍微复杂一些。比方说,您想提取每只猫的品种。XPath 查询将如下所示:

# Use .findall() with XPath to get all breeds
breeds = root_element.findall('.//cat/breed')

# Print the breeds
for breed in breeds:
    print(breed.text)

该脚本首先选择当前的根节点。然后,使用双斜线 (//) 选择根节点下的所有子元素。在本例中,//cat 会选择所有 *《cat》*节点。最后,单斜线 (/) 将从父节点中选择一个元素,因此 /breed 会获取 《cat》 下的第一个 《breed》 元素。所有这些信息都存储在 breeds 数组中,因此最后一步需要编写一个循环,从数组中选择每个 Element 项并打印其文本值。这就是结果:

Maine Coon
Siamese
Tabby

您甚至可以编写更复杂的 XPath 查询,只选出带有特定参数的项目。假设您只想得到三岁猫的名字,脚本会是这样的:

# Use .findall() with XPath to get names of cats that are 3 years old
cat_names_3_years_old = root_element.findall('.//cat[age="3"]/name')

# Print the names
for cat_name in cat_names_3_years_old:
    print(cat_name.text)

这个 XPath 与之前使用的类似,但它使用带参数的括号([])来只选择 《age》 值为 3 的 《cat》 节点。
XPath 最初可能看起来令人生畏,但它为从树中选择节点提供了无限的可能性和灵活性。请尝试使用其他查询、修改示例数据或通过不同的 XML 文件运行脚本,看看它们会返回什么结果。

八、最佳实践

现在,您已经学会了使用 Python 解析 XML 文档的基础知识,可以编写脚本并将它们集成到您的环境中,以实现有效的 XML 数据管理。虽然反复试验是成功编写脚本的最佳方法,但以下是一些需要牢记的宝贵提示,从长远来看会对您有所帮助:

**- 处理错误。**解析 XML 文档时,要为出现无效或缺失元素等错误做好准备。实施错误处理机制来处理这些情况,防止意外崩溃,使代码更加健壮。
- 兼容性。注意 XML 编码,确保您的 Python 环境支持 XML 文档中的编码。此外,考虑使用支持最新 XML 标准的库,以确保与各种 XML 格式和规范兼容。
**- 迭代解析。**对于大型 XML 文档,可考虑使用迭代解析来以节省内存的方式处理 XML。这包括一次一个地迭代 XML 元素,而不是将整个文档加载到内存中,从而降低内存问题的风险。
**- 关闭文件。**如果要从文件中解析 XML,最好在解析后关闭文件。这样可以确保系统资源得到及时释放,防止出现文件锁或资源泄漏的潜在问题。

获取更多信息或购买代理,请访问 Smartdaili。

九、总结

在本综合指南中,您已经学会了如何使用 Python 及其各种库来解析 XML 文档。ElementTree 和 XPath 都是非常有用的工具,可以完美地完成工作,因此选择使用哪一个完全取决于您。您可以在示例脚本的基础上运用这些知识,或者从头开始编写自己的脚本,从任何 XML 文件中解析 XML 数据。

获取更多信息或购买代理,请访问 Smartdaili。

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值