You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python ElementTree解析XML时findall方法部分路径返回空列表的原因咨询

为什么ElementTree的findall在某些XML路径下返回空列表?

首先来看你的代码和遇到的问题:

import xml.etree.ElementTree as ET  # 补充你可能省略的导入代码

input = ''' <stuff> <users> <user x="2"> <id>001</id> <name>Chuck</name> </user> <user x="7"> <id>009</id> <name>Brent</name> </user> </users> </stuff>'''
stuff=ET.fromstring(input)
print(stuff.findall('stuff')) #返回空列表
print(stuff.findall('users')) #返回包含1个元素的列表
print(stuff.findall('user')) #返回空列表
print(stuff.findall('users/user')) #返回包含2个元素的列表
print(stuff.findall('stuff/users')) #返回空列表
print(stuff.findall('stuff/users/user')) #返回空列表

核心原因:findall的路径是相对当前节点的

当你用ET.fromstring(input)解析这段XML时,返回的stuff变量本身就是XML的根元素<stuff>。所以所有findall的路径都是从这个根元素开始查找的,而不是从整个文档的“顶层”重新开始。

我们逐个分析你的疑问:

  1. stuff.findall('stuff'):你在根元素<stuff>下面找名为stuff的子元素,但根元素的直接子元素只有<users>,自然找不到,返回空列表。
  2. stuff.findall('users'):根元素的直接子元素就是<users>,所以能找到1个元素,符合预期。
  3. stuff.findall('user'):user是<users>的子元素,不是根元素的直接子元素,所以直接找user找不到,返回空。
  4. stuff.findall('users/user'):路径表示“根元素下的<users>子元素里的所有<user>”,这正好匹配XML结构,所以返回2个元素。
  5. stuff.findall('stuff/users'):你想找“根元素下的<stuff>子元素里的<users>”,但根元素下根本没有<stuff>子元素,所以返回空。
  6. stuff.findall('stuff/users/user'):和上面同理,路径的开头stuff在当前节点(根元素)下不存在,整个路径匹配失败,返回空。

和BeautifulSoup的区别

你之前用BeautifulSoup处理HTML时习惯的查找逻辑是全局查找,比如soup.find_all('user')会遍历整个文档树找所有<user>元素。但ElementTree的findall默认是相对路径查找,只在当前节点的直接或间接子元素中按路径匹配,不会全局遍历(除非你用XPath的特殊语法)。

解决方法

如果想实现类似BeautifulSoup的全局查找,或者更灵活的路径匹配,可以用XPath的//语法:

  • 全局找所有<user>:stuff.findall('.//user')
  • 全局找所有<users>:stuff.findall('.//users')

如果要写完整的绝对路径(从文档根开始),可以用/开头:

  • 找根元素下的<users>:stuff.findall('/stuff/users')
  • 找根元素下的<users>里的<user>:stuff.findall('/stuff/users/user')

这样就能得到你预期的结果啦~

内容的提问来源于stack exchange,提问作者user18344984

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 15:22:26