使用ElementTree解析XML时,核心技巧包括:利用ET.parse()或ET.fromstring()加载数据,通过getroot()获取根元素,遍历子元素并访问tag、attrib和text属性;使用find、findall和iter方法进行元素查找,结合命名空间字典处理带命名空间的标签,推荐用get()安全获取属性值。

在Python里解析XML文件,最常用的方法是使用内置的
xml.etree.ElementTree
lxml
ElementTree
要解析XML文件,我们通常会加载整个XML文档到内存中,然后像遍历树一样去访问其中的元素、属性和文本内容。
首先,你需要导入
ElementTree
ET
import xml.etree.ElementTree as ET
从文件解析: 如果你有一个XML文件(比如
data.xml
# data.xml 内容示例:
# <root>
# <item id="1">
# <name>苹果</name>
# <price currency="USD">1.99</price>
# </item>
# <item id="2">
# <name>香蕉</name>
# <price currency="USD">0.79</price>
# </item>
# </root>
try:
tree = ET.parse('data.xml')
root = tree.getroot() # 获取根元素
except FileNotFoundError:
print("错误:data.xml 文件未找到。")
except ET.ParseError as e:
print(f"错误:解析XML文件时出错 - {e}")从字符串解析: 如果你的XML数据是一个字符串,你可以用
ET.fromstring()
xml_string = """
<root>
<item id="3">
<name>橙子</name>
<price currency="EUR">1.20</price>
</item>
</root>
"""
root = ET.fromstring(xml_string)获取到
root
立即学习“Python免费学习笔记(深入)”;
print(f"根元素标签: {root.tag}")
# 遍历所有子元素
for child in root:
print(f"子元素标签: {child.tag}, 属性: {child.attrib}") # attrib 返回一个字典
# 获取特定子元素的文本内容
name_element = child.find('name')
if name_element is not None:
print(f" 商品名称: {name_element.text}")
price_element = child.find('price')
if price_element is not None:
print(f" 价格: {price_element.text}, 货币: {price_element.attrib.get('currency')}")
# 直接查找所有符合条件的元素
all_items = root.findall('item')
print(f"\n找到了 {len(all_items)} 个商品。")ElementTree
在我的实践中,掌握
ElementTree
ET.parse()
ET.fromstring()
parse
fromstring
getroot()
ElementTree
Element
tag
<name>
tag
'name'
attrib
<price currency="USD">
attrib
{'currency': 'USD'}text
<name>苹果</name>
text
'苹果'
text
tail
for child in parent_element:
find(tag)
tag
findall(tag)
tag
iter(tag=None)
iter()
root.iter('name')name
ElementTree
root.findall('./item/name')item
name
lxml
记住,
ElementTree
lxml
ElementTree
lxml
处理大型XML文件时,性能和内存占用就成了绕不开的话题。
ElementTree
lxml
xml.etree.ElementTree
ElementTree
ElementTree
lxml
ElementTree
ElementTree
lxml
lxml
libxml2
libxslt
ElementTree
lxml
iterparse
lxml
iterparse
lxml
pip install lxml
ElementTree
lxml
总结:
我的经验是,如果你的XML文件不大(比如几十MB以内),并且查询需求不复杂,
ElementTree
lxml
处理XML的命名空间和属性是日常工作中经常遇到的情况,尤其是在集成不同系统或者处理标准XML格式(如SOAP、RSS、Atom)时。
处理属性(Attributes):
属性相对直观,每个
Element
attrib
import xml.etree.ElementTree as ET
xml_data = """
<root>
<user id="123" status="active">
<name lang="en">John Doe</name>
<email>john.doe@example.com</email>
</user>
<user id="456" status="inactive">
<name lang="zh">张三</name>
</user>
</root>
"""
root = ET.fromstring(xml_data)
for user in root.findall('user'):
user_id = user.get('id') # 使用get()方法获取属性,更安全,如果属性不存在返回None
user_status = user.attrib.get('status', 'unknown') # 也可以使用字典的get方法,并提供默认值
print(f"User ID: {user_id}, Status: {user_status}")
name_element = user.find('name')
if name_element is not None:
name_text = name_element.text
name_lang = name_element.get('lang') # 获取name元素的lang属性
print(f" Name: {name_text}, Language: {name_lang}")这里我更推荐使用
element.get('attribute_name')None
element.attrib['attribute_name']
KeyError
处理命名空间(Namespaces):
命名空间是XML中一个稍微复杂但非常重要的概念,它用来避免元素和属性名称冲突。当XML文档中包含命名空间时,解析起来就需要一些特别的处理。
ElementTree
{namespace_uri}local_name<ns:item xmlns:ns="http://example.com/ns">
item
{http://example.com/ns}itemimport xml.etree.ElementTree as ET
xml_with_ns = """
<data xmlns="http://default.com/ns" xmlns:prod="http://products.com/ns">
<prod:item prod:id="A101">
<prod:name>Laptop</prod:name>
<price>1200</price>
</prod:item>
<prod:item prod:id="A102">
<prod:name>Mouse</prod:name>
<price>25</price>
</prod:item>
<info>Some general information</info>
</data>
"""
root = ET.fromstring(xml_with_ns)
# 1. 明确知道命名空间URI时:
# 注意:默认命名空间也会被ElementTree以URI形式处理
print("--- 明确知道命名空间URI ---")
default_ns_tag = "{http://default.com/ns}info"
info_element = root.find(default_ns_tag)
if info_element is not None:
print(f"Info (default NS): {info_element.text}")
# 对于带前缀的命名空间,同样需要使用完整的URI
prod_item_tag = "{http://products.com/ns}item"
for item in root.findall(prod_item_tag):
prod_id = item.get('{http://products.com/ns}id') # 属性的命名空间也要完整表示
prod_name_element = item.find('{http://products.com/ns}name')
price_element = item.find('{http://default.com/ns}price') # 注意这里price在默认命名空间下
name_text = prod_name_element.text if prod_name_element is not None else "N/A"
price_text = price_element.text if price_element is not None else "N/A"
print(f"Product ID: {prod_id}, Name: {name_text}, Price: {price_text}")
# 2. 使用命名空间字典进行查找 (更推荐的方式,尤其是当命名空间前缀在XML中不固定时)
# 需要创建一个字典,将前缀映射到URI
namespaces = {
'd': "http://default.com/ns", # 'd' 是我们自己定义的别名,可以随意取
'p': "http://products.com/ns"
}
print("\n--- 使用命名空间字典 ---")
# findall() 和 find() 方法可以接受一个命名空间字典作为第二个参数
# 这样,你就可以使用带有前缀的标签名进行查找了
for item in root.findall('p:item', namespaces):
# 获取带命名空间的属性,同样需要使用前缀
prod_id = item.get(f"{{{namespaces['p']}}}id") # 或者更直接的 item.get('{http://products.com/ns}id')
prod_name_element = item.find('p:name', namespaces)
price_element = item.find('d:price', namespaces) # price在默认命名空间下,所以用'd'
name_text = prod_name_element.text if prod_name_element is not None else "N/A"
price_text = price_element.text if price_element is not None else "N/A"
print(f"Product ID: {prod_id}, Name: {name_text}, Price: {price_text}")关键点:
ElementTree
xmlns="http://..."
ElementTree
{URI}tag_namefindall()
find()
{prefix: uri}总之,理解
ElementTree
lxml
ElementTree
以上就是python中怎么解析XML文件?的详细内容,更多请关注php中文网其它相关文章!
python怎么学习?python怎么入门?python在哪学?python怎么学才快?不用担心,这里为大家提供了python速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号