xmltodict设置xml_attribs=True仍无法获取顶层元素属性问题咨询
看起来你遇到的问题是xmltodict的item_callback回调里拿不到<cons>节点的属性,我之前也碰到过类似的情况,咱们一步步来排查和解决:
1. 先跳过item_callback,验证属性是否能被正常解析
先写一段简单的测试代码,不使用回调,直接解析整个XML看看结构:
import xmltodict # 用你的XML内容测试 test_xml = """<api> <cons id="79550" modified_dt="1526652449"> <firstname>Mackenzie</firstname> </cons> <cons id="79551" modified_dt="1526652549"> <firstname>Joe</firstname> </cons> </api>""" result = xmltodict.parse(test_xml, xml_attribs=True) print(result["api"]["cons"])
运行这段代码,你应该能看到每个cons字典里包含@id和@modified_dt键。如果这个没问题,说明属性本身是可以被xmltodict解析到的,问题出在回调的用法上。
2. 排查item_callback的参数和版本问题
检查回调触发的节点路径
修改你的handler函数,打印出第一个参数(节点路径),确认回调确实在处理<cons>节点:
def handler(path, cons): print(f"当前处理的节点路径: {path}") print(f"节点内容: {cons}") mc = MatchChecker(cons) mc.check() return True
如果路径显示为('api', 'cons'),说明确实在处理每个<cons>节点,这时候如果还是看不到属性,大概率是xmltodict版本的问题。
升级xmltodict到最新版本
旧版的xmltodict在item_callback和xml_attribs=True组合使用时可能存在bug,执行以下命令升级:
pip install --upgrade xmltodict
3. 替代方案:直接遍历解析后的字典
如果你只是想逐个处理<cons>节点,不一定非要用item_callback,可以直接遍历解析后的结果,这种方式更直观:
result = xmltodict.parse(apiResult.body, xml_attribs=True) for cons in result["api"]["cons"]: # 这里能正常拿到@id和@modified_dt print(cons["@id"], cons["@modified_dt"]) mc = MatchChecker(cons) mc.check()
这种方法适合XML文件不是特别大的场景,避免了回调带来的潜在问题。
4. 更灵活的替代工具:lxml
如果xmltodict的回调始终不符合你的需求,推荐用lxml来解析,它能更精准地控制节点和属性的提取:
from lxml import etree # 解析XML内容 root = etree.fromstring(apiResult.body) # 遍历所有cons节点 for cons_node in root.xpath("//cons"): # 提取属性 cons_id = cons_node.get("id") modified_dt = cons_node.get("modified_dt") # 提取子元素内容 firstname = cons_node.find("firstname").text # 组装成你需要的字典 cons_dict = { "id": cons_id, "modified_dt": modified_dt, "firstname": firstname # 其他子元素按需添加 } mc = MatchChecker(cons_dict) mc.check()
lxml的xpath语法非常强大,适合处理复杂结构的XML文档。
内容的提问来源于stack exchange,提问作者Steve Cohen
相关产品推荐
相关产品推荐

