如何用Python读取根标签含命名空间的XML(TCX)文件?
解决带命名空间的TCX文件Python解析问题
从plotaroute.com生成的TCX文件,根标签包含Garmin官方的XML命名空间声明,直接使用Python的xml.etree.ElementTree按普通路径查找节点时会匹配失败,只能通过手动删除命名空间才能正常解析。以下是无需修改原始文件的解决方案:
方法一:显式指定命名空间映射(推荐)
TCX文件中所有元素都属于http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2命名空间,只需在查找时通过namespaces参数传递映射,路径中添加对应前缀即可:
from dotenv import load_dotenv import os from xml.etree import ElementTree from pathlib import Path load_dotenv() data_folder = Path(os.getenv('DATA_FOLDER')) TCX_full = data_folder / "Poudre_Up024.tcx" # 定义TCX命名空间映射,前缀可自定义(这里用tcx) ns = {'tcx': 'http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2'} dom = ElementTree.parse(TCX_full) # 查找节点时添加命名空间前缀 trackpoints = dom.findall('tcx:Courses/tcx:Course/tcx:Track/tcx:Trackpoint', namespaces=ns) i = 0 for t in trackpoints: # 子节点同样需要带命名空间前缀 lat = float(t.find('tcx:Position/tcx:LatitudeDegrees', namespaces=ns).text) long = float(t.find('tcx:Position/tcx:LongitudeDegrees', namespaces=ns).text) alt = float(t.find('tcx:AltitudeMeters', namespaces=ns).text) dist_meters = float(t.find('tcx:DistanceMeters', namespaces=ns).text) print('%5d %10.6f %10.6f %6.1f %8.2f' % (i, lat, long, alt, dist_meters)) i += 1
方法二:自动提取命名空间(适配不同TCX版本)
如果不想手动写命名空间字符串,可以从根节点自动提取命名空间,再拼接标签名进行查找:
from dotenv import load_dotenv import os from xml.etree import ElementTree from pathlib import Path load_dotenv() data_folder = Path(os.getenv('DATA_FOLDER')) TCX_full = data_folder / "Poudre_Up024.tcx" dom = ElementTree.parse(TCX_full) root = dom.getroot() # 从根标签中提取命名空间 namespace = root.tag.split('}')[0].strip('{') # 遍历所有Trackpoint节点 trackpoints = [] for elem in root.iter(): if elem.tag == f'{{{namespace}}}Trackpoint': trackpoints.append(elem) i = 0 for t in trackpoints: # 拼接命名空间和标签名查找子节点 lat = float(t.find(f'{{{namespace}}}Position/{{{namespace}}}LatitudeDegrees').text) long = float(t.find(f'{{{namespace}}}Position/{{{namespace}}}LongitudeDegrees').text) alt = float(t.find(f'{{{namespace}}}AltitudeMeters').text) dist_meters = float(t.find(f'{{{namespace}}}DistanceMeters').text) print('%5d %10.6f %10.6f %6.1f %8.2f' % (i, lat, long, alt, dist_meters)) i += 1
问题原因说明
原代码直接使用Courses/Course/Track/Trackpoint路径查找,而带命名空间的XML中,每个元素的标签实际格式为{命名空间}标签名(比如{http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2}Trackpoint),因此普通路径无法匹配到任何节点,导致程序无输出。
内容的提问来源于stack exchange,提问作者virtualdynamo
相关产品推荐
相关产品推荐

