使用带有ns的标记和属性的python xml xpath查询
我一定是做了一些内在的错误,我所看到的每一个例子和搜索,所以似乎表明这是可行的 我正在尝试使用带有lxml etree库的XPath搜索来解析garmin tcx文件:使用带有ns的标记和属性的python xml xpath查询,python,xml,xpath,xml-parsing,lxml,Python,Xml,Xpath,Xml Parsing,Lxml,我一定是做了一些内在的错误,我所看到的每一个例子和搜索,所以似乎表明这是可行的 我正在尝试使用带有lxml etree库的XPath搜索来解析garmin tcx文件: <?xml version="1.0" encoding="UTF-8" standalone="no" ?> <TrainingCenterDatabase xmlns="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2" xmlns:xsi
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<TrainingCenterDatabase xmlns="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2 http://www.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd">
<Workouts>
<Workout Sport="Biking">
<Name>3P2 WK16 - 3</Name>
<Step xsi:type="Step_t">
<StepId>1</StepId>
<Name>[MP19]6:28-6:38</Name>
<Duration xsi:type="Distance_t">
<Meters>13000</Meters>
</Duration>
<Intensity>Active</Intensity>
<Target xsi:type="Speed_t">
<SpeedZone xsi:type="PredefinedSpeedZone_t">
<Number>2</Number>
</SpeedZone>
</Target>
</Step>
......
</Workout>
</Workouts>
</TrainingCenterDatabase>
但事实似乎并非如此。我尝试了许多删除/添加名称空间的组合,但都没有效果。如果我删除属性搜索并将其保留为“//xsi:SpeedZone”
,则返回:
<Element {http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2}SpeedZone at 0x2595188>
如我所料
我想我可以在for循环中完成它,但我觉得在一条线上就应该可以了 解决此问题的一种方法是避免指定属性名称,并使用
*
:
.//xsi:SpeedZone[@*='PredefinedSpeedZone_t']
另一个选项(不像前一个选项那么棒)是实际获取所有SpeedZone
标记,并检查循环中的属性值:
attribute_name = '{%s}type' % root.nsmap['xsi']
for speed_zone in root.xpath(".//xsi:SpeedZone", namespaces=xsi):
if speed_zone.attrib.get(attribute_name) == 'PredefinedSpeedZone_t':
print speed_zone
希望这会有所帮助。如果其他方法都失败,您仍然可以使用
".//xsi:SpeedZone[@*[name() = 'xsi:type' and . = 'PredefinedSpeedZone_t']]"
使用
name()
在问题和其他两个答案中的Python代码中,xsi
前缀绑定到http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2
URI。但是在包含Garmin数据的XML文档中,xsi
绑定到http://www.w3.org/2001/XMLSchema-instance
因为这里有两个名称空间,所以我认为下面的代码可以更清楚地描述正在发生的事情。与tcd
前缀关联的名称空间是默认名称空间
from lxml import etree
NSMAP = {"tcd": "http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2",
"xsi": "http://www.w3.org/2001/XMLSchema-instance"}
root = etree.parse('file.tcx')
for speed_zone in root.xpath(".//tcd:SpeedZone[@xsi:type='PredefinedSpeedZone_t']",
namespaces=NSMAP):
print speed_zone
输出:
<Element {http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2}SpeedZone at 0x25b7e18>
谢谢,通配符属性完成了这项工作,并为我的OCD提供了它所需的一行代码:)我想XPath和etree支持之间有些奇怪。我仍然需要重新阅读您的答案3到4次,但一旦单击,它看起来非常明显。不知道为什么我不能早点发现。我认为这应该得到正确的答案,所以编辑它。
<Element {http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2}SpeedZone at 0x25b7e18>