Python中XML数据的解析方法
在开发过程中,常需要从XML文件中提取数据进行处理,Python提供了多种解析方法
一、ElementTree模块应用
该模块是Python标准库中的核心解析工具,适用于常规数据提取场景
操作流程:
- 引入库:
import xml.etree.ElementTree as ET - 加载数据源:
- 文件读取:
xml_tree = ET.parse('data.xml') - 字符串解析:
main_element = ET.fromstring(xml_data)
- 获取主节点:
root_node = xml_tree.getroot() - 数据遍历:
- 直接子节点访问:
for item in root_node: - 条件查询:使用find/findall方法定位特定节点
- 内容提取:通过节点.text属性获取值
示例
示例XML结构
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<item>
<name>书籍一</name>
<author>作者A</author>
<cost>19.9</cost>
</item>
<item>
<name>书籍二</name>
<author>作者B</author>
<cost>29.9</cost>
</item>
</catalog>
import xml.etree.ElementTree as ET
# 读取文件
xml_doc = ET.parse('books.xml')
root = xml_doc.getroot()
# 遍历所有条目
for product in root.findall('item'):
title = product.find('name').text
author = product.find('author').text
print(f"名称: {title}, 作者: {author}")
# 价格节点遍历
for price in root.iter('cost'):
print(f"单价: {price.text}")
二、DOM树形解析方法
适用于需要完整文档结构操作的场景,但内存消耗较高
操作流程:
- 引入库:
from xml.dom import minidom - 加载文档:
document = minidom.parse('data.xml') - 获取根节点:
doc_root = document.documentElement - 节点操作:
- 使用childNodes属性遍历
- 通过getElementsByTagName查找节点
- 使用getElementById定位特定节点
- 属性获取:node.getAttribute("属性名")
- 文本内容:node.firstChild.data
from xml.dom import minidom
doc = minidom.parse('test.xml')
print(doc.nodeName)
print(doc.firstChild.tagName)
items = doc.getElementsByTagName("item")
print(len(items))
for item in items:
name = item.getElementsByTagName('name')[0].firstChild.data
print(name)
三、命名空间处理方案
基础概念说明
- 命名空间通过URI标识,通常以xmlns声明
- 示例格式:
<data xmlns="http://example.com/schema">
<entry>内容</entry>
</data>
- 带命名空间的元素表示为ns:element
Python处理步骤
第一步:创建命名空间映射
namespace_map = {
'ns': 'http://example.com/schema',
'prefix': 'http://other.namespace'
}
第二步:在查询时使用命名空间前缀
# 单个节点查询
target_node = root.find('ns:content', namespace_map)
# 多个节点查询
nodes_list = root.findall('ns:entry', namespace_map)
完整示例
import xml.etree.ElementTree as ET
# 带命名空间的XML数据
xml_data = '''
<root xmlns:ns="http://example.com/schema">
<ns:entry>数据1</ns:entry>
<ns:entry>数据2</ns:entry>
</root>
'''
# 解析处理
root = ET.fromstring(xml_data)
ns_map = {'ns': 'http://example.com/schema'}
# 带命名空间的查询
entries = root.findall('ns:entry', ns_map)
for entry in entries:
print(entry.text)