使用xml.etree.ElementTree筛选读取XML中TypeOfVessel非空条目问题求助
优化Python读取XML并筛选非空TypeOfVessel条目
首先看你的代码和XML结构,有几个关键问题需要调整,才能实现你要的「仅读取TypeOfVessel字段值不为空的ConsolidatedList条目」需求:
原代码的核心问题
- 忽略XML命名空间:你的XML根节点声明了默认命名空间
http://schemas.datacontract.org/2004/07/,所有子元素(比如ConsolidatedList、RegimeName)都属于这个命名空间,直接用entry.find('RegimeName')会找不到元素,大概率会抛出AttributeError - 未实现筛选逻辑:代码只是打印
TypeOfVessel,没有判断它是否非空 - 未处理
i:nil="true"属性:XML里用这个属性标记元素为空,不能只靠text是否存在来判断
优化后的代码
import xml.etree.ElementTree as ET def parse_consolidated_list(): # 定义命名空间映射,简化元素查找 ns = { "ns": "http://schemas.datacontract.org/2004/07/", "i": "http://www.w3.org/2001/XMLSchema-instance" } tree = ET.parse('ListRead.xml') root = tree.getroot() # 查找所有ConsolidatedList条目 consolidated_entries = root.findall('.//ns:ConsolidatedList', namespaces=ns) for entry in consolidated_entries: # 获取TypeOfVessel元素,同时处理命名空间 type_of_vessel_elem = entry.find('ns:TypeOfVessel', namespaces=ns) # 判断TypeOfVessel是否非空:元素存在 + 没有nil属性 + text不为空且非空白 is_valid = ( type_of_vessel_elem is not None and type_of_vessel_elem.get('i:nil', 'false') != 'true' and type_of_vessel_elem.text is not None and type_of_vessel_elem.text.strip() != '' ) if is_valid: # 读取其他字段(同样处理命名空间和nil属性) regime_name = entry.find('ns:RegimeName', namespaces=ns).text tonnage_elem = entry.find('ns:TonnageOfVessel', namespaces=ns) tonnage_of_vessel = tonnage_elem.text if (tonnage_elem is not None and tonnage_elem.get('i:nil', 'false') != 'true') else None print(f"有效条目:") print(f"RegimeName: {regime_name}") print(f"TonnageOfVessel: {tonnage_of_vessel}") print(f"TypeOfVessel: {type_of_vessel_elem.text}\n") if __name__ == "__main__": parse_consolidated_list()
关键优化点说明
- 命名空间处理:用
namespaces参数和短别名(ns)统一查找元素,避免每次写完整的命名空间URI - 严格的非空判断:同时检查元素是否存在、是否标记为
nil、文本内容是否非空且非空白,覆盖XML里的所有空值场景 - 代码规范:函数名、变量名改用PEP8规范的小写加下划线,增加
if __name__ == "__main__"让代码可以直接独立运行 - 容错性:读取
TonnageOfVessel时做了空值处理,避免因为元素不存在或为nil导致报错
运行这段代码后,只会输出TypeOfVessel为Bunkering Vessel的那个条目,完全符合你的需求。
内容的提问来源于stack exchange,提问作者Letoncse
相关产品推荐
相关产品推荐

