I must be doing something inherently wrong here, every example I've seen and search for on SO seems to suggest this would work.
I'm trying to use an XPath search with lxml etree library to parse a garmin tcx file:
<?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>
I'd like to return the SpeedZone Element only where the type is PredefinedSpeedZone_t. I thought I'd be able to do:
root = ET.parse(open('file.tcx'))
xsi = {'xsi': 'http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2'}
for speed_zone in root.xpath(".//xsi:SpeedZone[@xsi:type='PredefinedSpeedZone_t']", namespaces=xsi):
print speed_zone
Though this doesn't seem to be the case. I've tried lots of combinations of removing/adding namespaces and to no avail. If I remove the attribute search and leave it as ".//xsi:SpeedZone"
then this does return:
<Element {http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2}SpeedZone at 0x2595188>
as I'd expect.
I guess I could do it inside the for loop but it just feels like it should be possible on one line!