内容目录
原文链接:http://www.juzicode.com/python-module-xml/
XML(可扩展标记语言)是一种基于文本的标记语言,拥有自定义标签、树状结构、严格语法(区分大小写、标签闭合)及高可读性等特点。其设计注重数据内容与格式分离,支持跨平台和扩展性,适用于异构系统间的结构化数据交换。主要用途涵盖配置文件(如软件设置)、数据传输(如Web服务、RSS)、文档存储(如Office文件格式)及标准化数据共享,凭借独立于软硬件的特性,成为通用数据描述与交换的核心工具。
xml模块是Python标准库中用于处理 XML 数据的模块,提供解析、生成和修改 XML 文档的功能。支持 DOM 和 SAX 解析模式,适用于配置文件处理、数据交换和 Web 服务等场景。
应用场景
- 配置文件:读写 XML 格式的系统配置
- 数据交换:处理 SOAP/RSS 等 XML 协议数据
- 文档处理:生成符合行业标准的 XML 文档
- Web 服务:解析 API 返回的 XML 响应
安装或导入
Python的内置标准库,直接导入使用:
import xml.etree.ElementTree as ET
基本用法
以下示例展示 XML 文档的解析、创建等基础操作。
1. 解析 XML 文件
使用 ElementTree 解析 XML 文件并遍历元素。parse() 方法加载文件,iter() 遍历节点。
#juzicode.com/VX公众号:juzicode
import xml.etree.ElementTree as ET
tree = ET.parse('data.xml')
root = tree.getroot()
for child in root:
print(f"Tag: {child.tag}, Attr: {child.attrib}")
data.xml 内容为:
<root>
<item id="1">A</item>
<item id="2">B</item>
</root>
运行结果:
Tag: item, Attr: {'id': '1'}
Tag: item, Attr: {'id': '2'}
2. 创建 XML 文档
通过 Element 和 SubElement 构建 XML 结构。ET.Element() 创建根节点,ET.dump() 输出文档。
#juzicode.com/VX公众号:juzicode
import xml.etree.ElementTree as ET
root = ET.Element("catalog")
book = ET.SubElement(root, "book", id="bk101")
title = ET.SubElement(book, "title")
title.text = "Python Guide"
ET.dump(root)
运行结果:
<catalog>
<book id="bk101">
<title>Python Guide</title>
</book>
</catalog>
3. 修改 XML 内容
定位元素并修改属性与文本。find() 方法查找子元素,set() 修改属性。
#juzicode.com/VX公众号:juzicode
import xml.etree.ElementTree as ET
root = ET.fromstring('<item><name>Old</name></item>')
name = root.find('name')
name.text = "New"
name.set('updated', 'true')
ET.dump(root)
运行结果:
<item>
<name updated="true">New</name>
</item>
4. 查找元素
使用 XPath 表达式查询元素。findall() 支持 XPath 语法定位节点。
#juzicode.com/VX公众号:juzicode
import xml.etree.ElementTree as ET
xml_data = '''
<users>
<user role="admin">Alice</user>
<user role="user">Bob</user>
</users>
'''
root = ET.fromstring(xml_data)
admins = root.findall(".//user[@role='admin']")
print([elem.text for elem in admins])
运行结果:
['Alice']
5. 写入 XML 文件
将内存中的 XML 树写入文件。ElementTree.write() 方法实现持久化存储。
#juzicode.com/VX公众号:juzicode
import xml.etree.ElementTree as ET
root = ET.Element("config")
ET.SubElement(root, "entry", key="lang").text = "Python"
tree = ET.ElementTree(root)
tree.write("output.xml", encoding="utf-8", xml_declaration=True)
生成文件内容:
<?xml version='1.0' encoding='utf-8'?>
<config>
<entry key="lang">Python</entry>
</config>
6. 处理 XML 命名空间
注册命名空间并解析带前缀的 XML。使用 register_namespace() 避免前缀冲突。
#juzicode.com/VX公众号:juzicode
import xml.etree.ElementTree as ET
ET.register_namespace('ns', 'http://juzicode.com')
xml_data = '''
<ns:root xmlns:ns="http://juzicode.com">
<ns:item>Test</ns:item>
</ns:root>
'''
root = ET.fromstring(xml_data)
item = root.find('ns:item', {'ns': 'http://juzicode.com'})
print(item.text)
运行结果:
Test
高级功能
以下示例展示 XML 处理的进阶用法,可以处理一些复杂数据结构、满足性能需求。
1. SAX 解析大文件
使用 SAX 解析器处理大型 XML 文件。通过事件驱动模型节省内存。
#juzicode.com/VX公众号:juzicode
import xml.sax
class MyHandler(xml.sax.ContentHandler):
def startElement(self, name, attrs):
print(f"Start: {name}")
parser = xml.sax.make_parser()
parser.setContentHandler(MyHandler())
parser.parse("big.xml")
big .xml 内容为:
<?xml version='1.0' encoding='UTF-8'?>
<data>
<item>Content 1</item>
<item>Content 2</item>
<item>Content 3</item>
<metadata>
<author>XML Generator</author>
</metadata>
<item>Content 4</item>
<item>Content 5</item>
</data>
运行结果:
Start: data
Start: item
Start: item
Start: item
Start: metadata
Start: author
Start: item
Start: item
2. 生成 CDATA 段
通过扩展函数生成 CDATA 内容。自定义 Element 的子类处理特殊标记。
#juzicode.com/VX公众号:juzicode
def CDATA(text):
element = ET.Element('![CDATA[')
element.text = text
return element
root = ET.Element("data")
root.append(CDATA("特殊内容 & 符号"))
ET.dump(root)
运行结果:
<data>
<![CDATA[特殊内容 & 符号]]>
</data>
3. 流式解析大文件
使用 iterparse 增量解析 XML 文件。及时清除已处理元素节省内存。
#juzicode.com/VX公众号:juzicode
import xml.etree.ElementTree as ET
for event, elem in ET.iterparse("big.xml", events=("start", "end")):
if event == "end" and elem.tag == "item":
print(elem.text)
elem.clear()
big .xml 内容为:
<?xml version='1.0' encoding='UTF-8'?>
<data>
<item>Content 1</item>
<item>Content 2</item>
<item>Content 3</item>
<metadata>
<author>XML Generator</author>
</metadata>
<item>Content 4</item>
<item>Content 5</item>
</data>
运行结果:
Content 1
Content 2
Content 3
Content 4
Content 5
4. 转换 XML 到字典
递归遍历 XML 节点生成 Python 字典。适用于将 XML 数据转换为 JSON 格式。
#juzicode.com/VX公众号:juzicode
def xml_to_dict(element):
return {
**element.attrib,
"text": element.text,
"children": [xml_to_dict(child) for child in element]
}
root = ET.fromstring('<root><item id="1">A</item></root>')
print(xml_to_dict(root))
运行结果:
{
"text": None,
"children": [{
"id": "1",
"text": "A",
"children": []
}]
}
总结
xml 模块支持 DOM 和 SAX 两种解析模式,具有完整的 XML 标准兼容性、灵活的内存与性能平衡方案。该模块是处理 XML 数据的瑞士军刀,通过合理选择解析模式和扩展方法,可以应对从简单配置到企业级数据交换的各种需求。