2015-12-24 96 views
1

屬性值我有一個.tcx(XML)文件,使用下面的模式:Python腳本改變.tcx文件(XML)

<Activities> 
<Activity> 
<Lap StartTime="2015-12-24T08:12:18.969Z"> 
<TotalTimeSeconds>4069.0</TotalTimeSeconds> 
<DistanceMeters>30458.794921875</DistanceMeters> 
<MaximumSpeed>43.36123275756836</MaximumSpeed> 
<Calories>2286</Calories> 
<AverageHeartRateBpm><Value>144</Value></AverageHeartRateBpm><MaximumHeartRateBpm><Value>169</Value></MaximumHeartRateBpm> 
<Intensity>Active</Intensity> 
<Cadence>87</Cadence> 
<TriggerMethod>Manual</TriggerMethod> 

<Track> 
    <Trackpoint> 
     <Time>2015-12-24T08:12:19.969Z</Time> 
     <Position><LatitudeDegrees>45.4917</LatitudeDegrees><LongitudeDegrees>9.16198</LongitudeDegrees></Position> 
     <AltitudeMeters>124.018</AltitudeMeters> 
     <DistanceMeters>0.0</DistanceMeters> 
     <SensorState>Present</SensorState> 
     <Extensions><TPX xmlns="http://www.garmin.com/xmlschemas/ActivityExtension/v2"><Watts>0</Watts></TPX></Extensions></Trackpoint> 


... 
</Track> 
</Lap> 
</Activity> 
</Activities> 

,並需要改變(雙)瓦特屬性。 想要一個簡單的python腳本

回答

0

您的最後兩個元素標記需要關閉標記,並且您有一個Watts元素不是屬性。以下是如何使用您的文件結構來完成此操作。

Python爲此提供了ElementTree庫。下面的腳本將完成你想要的:

import xml.etree.ElementTree as ET 

tree = ET.parse("test.tcx") 

tpxns = "http://www.garmin.com/xmlschemas/ActivityExtension/v2" 
for watts in tree.iter("{%s}Watts"%tpxns): 
    watts.text = str(2*int(watts.text)) 

tree.write("testnew.tcx") 

這裏我導入ElementTree庫,併爲它使用更簡單的名稱。解析函數從您的文件創建一個ElementTree對象。我遍歷該文件以查找所有Watts元素(因爲這些元素出現在名稱空間中,實際上我需要查找使用字符串格式設置構建的Watts)。

當我找到這樣的元素時,我將內部文本設置爲之前值的兩倍(先轉換爲int,然後再轉換爲字符串)。

最後,我寫出新的xml文件。如果我想,我可以在這裏覆蓋原始文件。

查看ElementTree模塊的文檔,如果你需要做更多的事情。它爲使用XML提供了非常強大的工具。如果你需要更多的功能,那麼還有更強大的庫(例如我喜歡lxml)。

+0

謝謝你,這就是正是我的目標爲。我嘗試使用ElementTree庫,但無法搜索Watts元素,因爲我缺少名稱空間概念。 –

1

只需運行一個XSLT腳本。不需要Python循環或昂貴的XPath(//)。作爲信息,XSLT是一種聲明性的專用編程語言,專門用於重新構造,重新設計或重新格式化XML文檔以滿足各種最終用途需求。像大多數通用語言,如Java,C#,Perl,PHP,VB一樣,Python在其lxml模塊中配備了XSLT 1.0處理器。

下面運行標識轉換來複制整個文檔,然後將任何Watts節點中的當前值乘以2.我在XSLT中聲明命名空間doc以引用Watts元素。

XSLT(另存爲的.xsl或.xslt)

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
       xmlns:doc="http://www.garmin.com/xmlschemas/ActivityExtension/v2"> 
<xsl:output version="1.0" encoding="UTF-8" indent="yes" /> 
<xsl:strip-space elements="*"/> 

    <!-- Identity Transform --> 
    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="doc:Watts"> 
    <xsl:copy> 
     <xsl:value-of select=". * 2"/> 
    </xsl:copy> 
    </xsl:template> 

</xsl:transform> 

的Python腳本

import lxml.etree as ET 

dom = ET.parse('Input.xml') 
xslt = ET.parse('XSLTScript.xsl') 

transform = ET.XSLT(xslt) 
newdom = transform(dom) 

tree_out = ET.tostring(newdom, encoding='UTF-8', pretty_print=True, xml_declaration=True) 

xmlfile = open('Output.xml') 
xmlfile.write(tree_out) 
xmlfile.close()