tutorial open make libreria leer example etree con archivo python xml parsing xpath beautifulsoup

python - open - xml etree elementtree example



¿Cómo puedo tomar series de datos del archivo xml o tcx? (3)

Quiero tratar los datos del archivo .tcx (formato xml) entre etiquetas específicas con Python.
El formato de archivo es como sigue.

<Track> <Trackpoint> <Time>2015-08-29T22:04:39.000Z</Time> <Position> <LatitudeDegrees>37.198049426078796</LatitudeDegrees> <LongitudeDegrees>127.07204628735781</LongitudeDegrees> </Position> <AltitudeMeters>34.79999923706055</AltitudeMeters> <DistanceMeters>7.309999942779541</DistanceMeters> <HeartRateBpm> <Value>102</Value> </HeartRateBpm> <Cadence>76</Cadence> <Extensions> <TPX xmlns="http://www.garmin.com/xmlschemas/ActivityExtension/v2"> <Watts>112</Watts> </TPX> </Extensions> </Trackpoint> ....Lots of <Trackpoint> ... </Trackpoint> </Track>

Eventualmente, haré una tabla de Datos con columnas de ''Lattitude, Altitude, ... Watts''.
Primero traté de hacer una lista a partir de datos modificados (como Watts ... / Watts) con BeautifulSoup, xpath, etc. Pero soy un novato para manejar estas herramientas. ¿Cómo puedo obtener datos entre las etiquetas en un archivo xml con Python?


Puede usar el módulo lxml , junto con XPath . lxml es bueno para analizar XML / HTML, recorrer árboles de elementos y devolver texto / atributos de elementos. Puede seleccionar elementos particulares, conjuntos de elementos o atributos de elementos usando XPath . Usando sus datos de ejemplo:

content = '''''' <Track> <Trackpoint> <Time>2015-08-29T22:04:39.000Z</Time> <Position> <LatitudeDegrees>37.198049426078796</LatitudeDegrees> <LongitudeDegrees>127.07204628735781</LongitudeDegrees> </Position> <AltitudeMeters>34.79999923706055</AltitudeMeters> <DistanceMeters>7.309999942779541</DistanceMeters> <HeartRateBpm> <Value>102</Value> </HeartRateBpm> <Cadence>76</Cadence> <Extensions> <TPX xmlns="http://www.garmin.com/xmlschemas/ActivityExtension/v2"> <Watts>112</Watts> </TPX> </Extensions> </Trackpoint> ....Lots of <Trackpoint> ... </Trackpoint> </Track> '''''' from lxml import etree tree = etree.XML(content) time = tree.xpath(''Trackpoint/Time/text()'') print(time)

Salida

[''2015-08-29T22:04:39.000Z'']


Incluso puede usar el módulo lxml para convertir XML a CSV (para una posterior importación en un dataframe, hoja de cálculo o tabla de base de datos) utilizando una lista iterada de Python en varios XPaths.

Observe que el último nodo de Watts es un XPath especial y más largo debido al escape del espacio de nombres especial, xlmns no registrado en XML de muestra.

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)

Además del archivo CSV, a continuación se muestra el resultado de la lista de datos de las columnas seleccionadas:

[[''37.198049426078796'', ''127.07204628735781'', ''34.79999923706055'', ''7.309999942779541'', ''112'']]


El programa Python https://github.com/cast42/vpower/blob/master/vpower.py itera sobre el archivo TCX especificado en la línea de comando y agrega un campo de potencia para todas las mediciones de la actividad de ciclismo. Utiliza la biblioteca lxml para la velocidad y porque trata con espacios de nombres. En versiones anteriores de este programa utilicé xml.etree.ElementTree pero encontré problemas con los espacios de nombres.