使用ElementTree解析NeTEX格式XML提取公交站点及票价信息方法
实现方案
完全可以不用多层嵌套for循环提取目标数据,XML解析库普遍支持的XPath查询能力可以直接定位目标节点,大幅简化代码逻辑,以下是具体实现方式:
方案1:使用Python标准库xml.etree.ElementTree实现
NeTEX格式XML自带标准命名空间,首先需要声明命名空间映射避免标签匹配失败,直接通过XPath路径定位ScheduledStopPointRef、站点、分区、票价相关节点即可,无需逐层遍历:
import xml.etree.ElementTree as ET # 声明NeTEX标准命名空间 NS = {'netex': 'http://www.netex.org.uk/netex'} # 加载XML文件 tree = ET.parse('/path/to/your/file.xml') root = tree.getroot() # 直接定位所有票价分区节点 for tariff_zone in root.findall('.//netex:TariffZone', namespaces=NS): # 提取分区名称、分区对应票价 zone_name = tariff_zone.findtext('./netex:Name', default='无', namespaces=NS) zone_price = tariff_zone.findtext('.//netex:Price/netex:Amount', default='无', namespaces=NS) # 定位该分区下关联的所有公交站点引用 for stop_ref in tariff_zone.findall('.//netex:ScheduledStopPointRef', namespaces=NS): # 提取ATCO编码(一般存储在ref属性中) atco_code = stop_ref.get('ref', '无') # 定位对应站点的详情节点 stop_node = root.find(f'.//netex:ScheduledStopPoint[@id="{atco_code}"]', namespaces=NS) if stop_node is None: continue # 提取公交站点名称 stop_name = stop_node.findtext('./netex:Name', default='无', namespaces=NS) # 输出四个目标字段 print(f"公交站点名称:{stop_name},ATCO编码:{atco_code},所属分区:{zone_name},分区票价:{zone_price}")
方案2:使用第三方库lxml实现(推荐处理大文件)
如果你的XML文件体积较大,推荐使用lxml库,它的XPath支持更完善、解析性能更高,API和标准库ElementTree基本兼容:
- 安装方式:执行
pip install lxml - 代码仅需修改导入语句即可:
# 替换导入语句即可,后续逻辑和方案1完全一致 from lxml import etree as ET
注意事项
- 你可以根据实际XML的节点结构微调XPath路径,即可适配不同的NeTEX数据规范
- 如果是超大型XML文件,可以使用
iterparse迭代解析能力,无需把整个文件加载到内存即可完成数据提取
内容的提问来源于stack exchange,提问作者Ananth
相关产品推荐
相关产品推荐

