This is an XML document with names . Therefore, you need to address the nodes using their respective namespaces.
The namespaces used in the document are defined above:
xmlns:tc2="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tp1="http://www.garmin.com/xmlschemas/TrackPointExtension/v1" xmlns="http://www.topografix.com/GPX/1/1"
So, the first namespace is mapped to tc2 short form and will be used in an element of type <tc2:foobar/> . The latter, which does not have a short form after xmlns , is called the default namespace, and it applies to all elements of the document that do not explicitly use the namespace, so this also applies to your <trkpt /> elements.
Therefore, you need to write root.iter('{http://www.topografix.com/GPX/1/1}trkpt') to select these items.
To get the time and height, you can use trkpt.find() to access these elements below the trkpt node, and then element.text to get the text content of these elements (unlike attributes like lat and lon ). In addition, since time and ele elements also use the default namespace, you will need to use the {namespace}element syntax to select these nodes.
So you can use something like this:
NS = 'http://www.topografix.com/GPX/1/1' header = ('lat', 'lon', 'ele', 'time') with open('output.csv', 'w') as f: writer = csv.writer(f) writer.writerow(header) root = lxml.etree.fromstring(x) for trkpt in root.iter('{%s}trkpt' % NS): lat = trkpt.get('lat') lon = trkpt.get('lon') ele = trkpt.find('{%s}ele' % NS).text time = trkpt.find('{%s}time' % NS).text row = lat, lon, ele, time writer.writerow(row)
For more information about XML namespaces, see Namespaces in the lxml tutorial and Wikipedia article on XML namespaces . Also see GPS eXchange format for details on the .gpx format.