用于更改.tcx文件(XML)中的属性值的Python脚本

时间:2015-12-24 18:13:05

标签: python xml

我有一个.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>

并且需要更改(加倍)Watts属性。 想要一个简单的python脚本

2 个答案:

答案 0 :(得分:1)

只需运行XSLT脚本即可。不需要Python循环或昂贵的XPath(doc)。作为信息,swt-4.5-win32-win32-x86_64是一种声明性的专用编程语言,专门用于重构,重新设计或重新格式化XML文档以满足各种最终用途需求。像大多数通用语言一样,如Java,C#,Perl,PHP,VB,Python在其lxml模块中配备了XSLT 1.0处理器。

下面运行一个标识转换,按原样复制整个文档,然后将任何Watts节点中的当前值乘以2.我在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> 以引用Watts元素。

XSLT (另存为.xsl或.xslt)

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()

Python 脚本

{{1}}

答案 1 :(得分: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元素(因为这些元素出现在命名空间中,我实际上需要查找{http://www.garmin.com/xmlschemas/ActivityExtension/v2} Watts,我使用字符串格式构建它。)

当我找到这样的元素时,我将内部文本设置为前一个值的两倍(先转换为int然后再转换为字符串)。

最后,我将新的xml文件写出来。如果我愿意,我可以在这里覆盖原始文件。

如果您需要做更多更好的事情,请查看ElementTree模块的文档。它提供了非常强大的工具来处理XML。如果你需要更多的功能(我喜欢lxml),那里有更强大的库。