You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python lxml无法访问XML孙标签,求解决方案

问题分析与解决思路

你遇到的核心问题是XML命名空间的处理不当——你的XML里既有默认命名空间(TrainingCenterDatabase/v2),又有ActivityExtension/v2这个子命名空间,所有元素的查找都必须带上对应的命名空间才能定位到,这也是为什么你的CSV只有表头的原因:根本没找到任何匹配的节点。

我来帮你一步步修正代码:

1. 简化XML解析流程

你不需要先parse再转成字符串,再用fromstring解析,直接用parse()后的getroot()拿到根节点就行,多余的解析步骤不仅没用,还可能引入额外问题。

2. 正确使用命名空间查找节点

  • 默认命名空间下的Trackpoint、Extensions需要用tcx前缀绑定的命名空间定位
  • TPX以及它下面的Speed、Watts属于ext前缀绑定的命名空间,查找时必须指定这个命名空间

修正后的完整代码

import lxml.etree as et
import csv

# 定义命名空间字典,用前缀简化写法
NS = {'tcx': 'http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2',
      'ext': 'http://www.garmin.com/xmlschemas/ActivityExtension/v2'}

# 直接解析XML文件并获取根节点
tree = et.parse('sample.tcx', parser=et.XMLParser(remove_comments=True))
root = tree.getroot()

header = ('Speed', 'Watts')
with open('output1.csv', 'w', newline='') as g:
    writer = csv.writer(g)
    writer.writerow(header)
    
    # 用XPath配合命名空间前缀,精准定位所有TPX节点
    for tpx in root.xpath('//tcx:Trackpoint/tcx:Extensions/ext:TPX', namespaces=NS):
        # 子节点Speed和Watts同样属于ext命名空间,必须指定前缀查找
        speed = tpx.find('ext:Speed', namespaces=NS).text
        watts = tpx.find('ext:Watts', namespaces=NS).text
        writer.writerow([speed, watts])

关键调整点说明

  • 用命名空间字典绑定前缀,让XPath写法更简洁,避免重复写冗长的命名空间URI
  • 使用xpath()代替iter(),配合前缀精准定位层级节点://tcx:Trackpoint/tcx:Extensions/ext:TPX 明确指定了每个层级元素所属的命名空间
  • 子节点Speed和Watts同样属于ext命名空间,所以find()时必须带上namespaces=NS和前缀ext:

这样运行后,就能正确提取到孙标签里的Speed和Watts值,写入CSV文件了。

内容的提问来源于stack exchange,提问作者vanoccupanther

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:33:41