[英]How can I make sure any data I grab from a spreadsheet has no xml content?
[英]How can I grab data series from xml or tcx file
我想使用Python处理特定标签之间的.tcx文件(xml形式)中的数据。
文件格式如下。
<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>
最终,我将使用“纬度,海拔高度,...瓦特”列创建数据表。
首先,我尝试使用BeautifulSoup,xpath等从标记的数据(如Watts ... / Watts)中列出一个列表。但是我是使用这些工具的新手。 如何使用Python捕获xml文件中标签之间的数据?
您可以将lxml
模块与XPath
一起使用。 lxml
非常适合解析XML / HTML,遍历元素树并返回元素文本/属性。 您可以使用XPath
选择特定元素,元素集或元素属性。 使用示例数据:
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)
输出量
['2015-08-29T22:04:39.000Z']
您甚至可以使用lxml
模块,使用跨各种XPath的迭代Python列表将XML转换为CSV(以便稍后导入到数据框,电子表格或数据库表中)。
注意,最后一个Watts
节点是特殊的,较长的XPath,因为它转义了特殊的名称空间, xlmns
未在示例XML中注册。
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)
除了CSV文件,以下是选定列的数据行列表输出:
[['37.198049426078796', '127.07204628735781', '34.79999923706055', '7.309999942779541', '112']]
Python程序https://github.com/cast42/vpower/blob/master/vpower.py遍历命令行中指定的TCX文件,并为所有骑单车活动测量添加功率字段。 它使用lxml库来提高速度,因为它处理名称空间。 在该程序的早期版本中,我使用了xml.etree.ElementTree,但是在命名空间方面遇到了问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.