You can even use the lxml module to convert XML to CSV (for subsequent import into a data table, table or database table) using a duplicate Python list for different XPaths.
Note that the last Watts node is a special, longer XPath due to escaping a special namespace, xlmns not registered in the XML sample.
import os, csv import lxml.etree as ET # SET DIRECTORY cd = os.path.dirname(os.path.abspath(__file__)) # LOAD XML FILE xmlfile = 'trackXML.xml' dom = ET.parse(os.path.join(cd, xmlfile)) # DEFINING COLUMNS columns = ['latitude', 'longitude', 'altitude', 'distance', 'watts'] # OPEN CSV FILE with open(os.path.join(cd,'trackData.csv'), 'w') as m: writer = csv.writer(m) writer.writerow(columns) nodexpath = dom.xpath('//Trackpoint') dataline = [] # FOR ONE-ROW CSV APPENDS datalines = [] # FOR FINAL OUTPUT for j in range(1,len(nodexpath)+1): dataline = [] # LOCATE PATH OF EACH NODE VALUE latitudexpath = dom.xpath('//Trackpoint[{0}]/Position/LatitudeDegrees/text()'.format(j)) dataline.append('') if latitudexpath == [] else dataline.append(latitudexpath[0]) longitudexpath = dom.xpath('//Trackpoint[{0}]/Position/LongitudeDegrees/text()'.format(j)) dataline.append('') if longitudexpath == [] else dataline.append(longitudexpath[0]) altitudexpath = dom.xpath('//Trackpoint[{0}]/AltitudeMeters/text()'.format(j)) dataline.append('') if altitudexpath == [] else dataline.append(altitudexpath[0]) distancexpath = dom.xpath('//Trackpoint[{0}]/DistanceMeters/text()'.format(j)) dataline.append('') if distancexpath == [] else dataline.append(distancexpath[0]) wattsxpath = dom.xpath("//Trackpoint[{0}]/*[name()='Extensions']/*[name()='TPX']/*[name()='Watts']/text()".format(j)) dataline.append('') if wattsxpath == [] else dataline.append(wattsxpath[0]) datalines.append(dataline) writer.writerow(dataline) print(datalines)
In addition to the CSV file, the following is a list of the datalines output from the selected columns:
[['37.198049426078796', '127.07204628735781', '34.79999923706055', '7.309999942779541', '112']]
source share