解析XML时存在有效值却返回NoneType,如何解决该问题?
解决ElementTree解析XML时name节点返回None的问题
嘿,这个问题我之前也踩过坑!核心原因是你没搞清楚xml.etree.ElementTree里find()方法的查找范围,再加上你的XML层级结构有点容易混淆,才导致了这个报错。
先帮你理清楚问题出在哪:
你的XML结构是嵌套的:stuff -> user(外层容器)-> user(实际用户节点)-> name。而stuff.find('name')只会在根节点stuff的直接子节点里查找,显然直接子节点里没有name,所以返回None,调用.text自然就触发AttributeError了。
下面给你几个可行的解决方案:
方案1:用XPath语法快速找到第一个name节点
如果你只需要获取第一个name的内容,可以用XPath的//语法,它会搜索当前节点的所有后代节点,找到第一个匹配的项:
import xml.etree.ElementTree as ET input=''' <stuff> <user> <user x='2' > <id>001</id> <name>chuck</name> </user> <user x ='7'> <id>009</id> <name>brent</name> </user> </user> </stuff> ''' stuff=ET.fromstring(input) # 用.//name搜索所有后代中的第一个name节点 name_node = stuff.find('.//name') # 先判断节点是否存在,避免再次触发NoneType报错 if name_node is not None: print(name_node.text)
运行后会输出:chuck
方案2:逐层遍历,获取所有name节点内容
如果你需要提取所有用户的name,可以精准定位到内层的user节点,再逐个提取:
import xml.etree.ElementTree as ET input=''' <stuff> <user> <user x='2' > <id>001</id> <name>chuck</name> </user> <user x ='7'> <id>009</id> <name>brent</name> </user> </user> </stuff> ''' stuff=ET.fromstring(input) # 先找到外层的user容器,再获取里面所有的内层user节点 inner_users = stuff.find('user').findall('user') for user in inner_users: print(user.find('name').text)
运行后会输出:
chuck brent
额外优化建议:调整XML结构减少混淆
你的XML里外层容器和实际用户节点都用了<user>标签,虽然语法合法,但很容易搞混层级。建议把外层容器改成<users>(复数形式),结构会更清晰:
<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.find('users').findall('user'),可读性会高很多,也不容易出错。
内容的提问来源于stack exchange,提问作者shashank shekhar
相关产品推荐
相关产品推荐

