Python解析XML文件检索嵌套子节点失败解决方案
问题原因
节点查找失败的核心原因是XML声明了默认命名空间:根节点配置的xmlns="http://www.egi.com/coordinates_mff"为默认命名空间,所有未带前缀的子节点都会自动归属到该命名空间下。直接使用纯标签名sensor查找时,ElementTree无法匹配到带命名空间的实际节点,因此返回空结果。输出的root.tag值'{http://www.egi.com/coordinates_mff}coordinates'是ElementTree标识带命名空间标签的标准格式,大括号内的内容即为命名空间URI。
解决方案
提供两种可直接运行的实现方式:
方法1:显式指定命名空间查找
先定义命名空间映射字典,查找节点时将命名空间和标签名组合匹配,不需要修改原始XML结构。
import xml.etree.ElementTree as ET tree = ET.parse("你的xml文件路径.xml") root = tree.getroot() # 命名空间映射,前缀可自定义,URI必须和XML中声明的完全一致 ns = {"egi": "http://www.egi.com/coordinates_mff"} sensor_result = [] # 遍历所有sensor节点,两种查找写法二选一即可 # 写法1:用iter拼接命名空间 for sensor in root.iter(f"{{{ns['egi']}}}sensor"): # 写法2:用findall配合xpath # for sensor in root.findall(".//egi:sensor", namespaces=ns): single_sensor = { "name": sensor.findtext("egi:name", default="", namespaces=ns), "number": int(sensor.findtext("egi:number", default=0, namespaces=ns)), "x": float(sensor.findtext("egi:x", default=0.0, namespaces=ns)), "y": float(sensor.findtext("egi:y", default=0.0, namespaces=ns)), "z": float(sensor.findtext("egi:z", default=0.0, namespaces=ns)) } sensor_result.append(single_sensor) # 输出结果验证 print(sensor_result)
运行后输出的第一条数据为:{'name': '', 'number': 1, 'x': 6.962, 'y': 5.382, 'z': -2.191},和XML内容完全匹配。
方法2:预处理移除所有命名空间
如果不想每次查找都携带命名空间前缀,可以在解析后遍历所有节点,把标签中的命名空间部分剔除,之后即可直接用纯标签名查找。
import xml.etree.ElementTree as ET tree = ET.parse("你的xml文件路径.xml") root = tree.getroot() # 遍历所有节点,移除标签中的命名空间片段 for elem in root.iter(): if "}" in elem.tag: elem.tag = elem.tag.split("}", 1)[1] sensor_result = [] # 直接用纯标签名查找即可 for sensor in root.iter("sensor"): single_sensor = { "name": sensor.findtext("name", default=""), "number": int(sensor.findtext("number", default=0)), "x": float(sensor.findtext("x", default=0.0)), "y": float(sensor.findtext("y", default=0.0)), "z": float(sensor.findtext("z", default=0.0)) } sensor_result.append(single_sensor)
选型提示:如果XML包含多个不同命名空间的节点,优先使用第一种显式命名空间的写法,避免不同命名空间下重名标签匹配错误;如果XML仅存在单个默认命名空间,且后续不需要处理命名空间相关逻辑,第二种写法代码更简洁。
内容的提问来源于stack exchange,提问作者Mathieu
相关产品推荐
相关产品推荐

