【发布时间】:2017-01-23 01:26:26
【问题描述】:
我正在尝试使用 XML 包读取 tcx 文件(来自自行车教练)。这个问题Import TCX into R using XML package 让我开始了。在 2011 年的示例中,数据如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<TrainingCenterDatabase xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2">
<Activities>
<Activity Sport="Running">
<Id>2011-10-30T16:05:48Z</Id>
<Lap StartTime="2011-10-30T16:05:48Z">
<TotalTimeSeconds>3855.99</TotalTimeSeconds>
<DistanceMeters>12498.8115</DistanceMeters>
<MaximumSpeed>4.45662498</MaximumSpeed>
<Calories>1011</Calories>
<Intensity>Active</Intensity>
<TriggerMethod>Manual</TriggerMethod>
<Track>
<Trackpoint>
<Time>2011-10-30T16:05:48Z</Time>
<Position>
<LatitudeDegrees>52.33613318</LatitudeDegrees>
<LongitudeDegrees>-1.58814317</LongitudeDegrees>
</Position>
<AltitudeMeters>77.5234375</AltitudeMeters>
<DistanceMeters>0.00000000</DistanceMeters>
</Trackpoint>
<Trackpoint>
<Time>2011-10-30T16:05:49Z</Time>
<Position>
<LatitudeDegrees>52.33614810</LatitudeDegrees>
<LongitudeDegrees>-1.58814283</LongitudeDegrees>
</Position>
<AltitudeMeters>77.5234375</AltitudeMeters>
<DistanceMeters>1.77584004</DistanceMeters>
</Trackpoint>
...
阅读本文的代码很简单:
library(XML)
doc = xmlParse("testfile.tcx")
basic = xmlToDataFrame(nodes <- getNodeSet(doc, "//ns:Trackpoint", "ns"))
我有一个更复杂的 tcx 文件:
<?xml version="1.0" encoding="utf-8"?>
<TrainingCenterDatabase xsi:schemaLocation="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2 http://www.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd" xmlns:ns5="http://www.garmin.com/xmlschemas/ActivityGoals/v1" xmlns:ns3="http://www.garmin.com/xmlschemas/ActivityExtension/v2" xmlns:ns2="http://www.garmin.com/xmlschemas/UserProfile/v2" xmlns="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns4="http://www.garmin.com/xmlschemas/ProfileExtension/v1" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Activities xmlns="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2">
<Activity Sport="Biking">
<Id>2017-01-21T17:33:40.86Z</Id>
<Lap StartTime="2017-01-21T17:33:40Z">
<TotalTimeSeconds>720</TotalTimeSeconds>
<DistanceMeters>3565.9106917557524</DistanceMeters>
<MaximumSpeed>5.39404950335725</MaximumSpeed>
<Calories>68</Calories>
<AverageHeartRateBpm>
<Value>123</Value>
</AverageHeartRateBpm>
<MaximumHeartRateBpm>
<Value>128</Value>
</MaximumHeartRateBpm>
<Intensity>Active</Intensity>
<Cadence>75</Cadence>
<TriggerMethod>Time</TriggerMethod>
<Track>
<Trackpoint>
<Time>2017-01-21T17:33:40Z</Time>
<DistanceMeters>4.68</DistanceMeters>
<Cadence>79</Cadence>
<Extensions>
<ns3:TPX>
<ns3:Watts>87</ns3:Watts>
<ns3:Speed>4.68072232948508</ns3:Speed>
</ns3:TPX>
</Extensions>
</Trackpoint>
<Trackpoint>
<Time>2017-01-21T17:33:41Z</Time>
<DistanceMeters>9.41</DistanceMeters>
<Cadence>81</Cadence>
<Extensions>
<ns3:TPX>
<ns3:Watts>88</ns3:Watts>
<ns3:Speed>4.726922499738</ns3:Speed>
</ns3:TPX>
</Extensions>
</Trackpoint>
</Track>
<Extensions>
<ns3:LX>
<AvgSpeed xmlns:ns3="http://www.garmin.com/xmlschemas/ActivityExtension/v2" xmlns="">4.45096542560575</AvgSpeed>
</ns3:LX>
<ns3:LX>
<ns3:MaxBikeCadence>111</ns3:MaxBikeCadence>
</ns3:LX>
<ns3:LX>
<ns3:MaxWatts>161</ns3:MaxWatts>
</ns3:LX>
<ns3:LX>
<ns3:AvgWatts>81</ns3:AvgWatts>
</ns3:LX>
</Extensions>
</Lap>
</Activity>
</Activities>
</TrainingCenterDatabase>
(中间省略了很多行)
我对每个 Trackpoint 都感兴趣。也就是说,我不关心最后一个 Trackpoint 之后的扩展,但我确实想要记录每个 Trackpoint 中记录的扩展(瓦特和速度)。
使用上面建议的代码生成以下内容:
> head(basic,2)
Time DistanceMeters Cadence Extensions HeartRateBpm
1 2017-01-21T17:33:40Z 4.68 79 874.68072232948508 <NA>
2 2017-01-21T17:33:41Z 9.41 81 884.726922499738 <NA>
意味着扩展名被提取,但被连接起来并且它们的名字丢失了。
IOW,我想要一个如下所示的数据框:
> head(basic,2)
Time DistanceMeters Cadence Watts Speed HeartRateBpm
1 2017-01-21T17:33:40Z 4.68 79 87 4.68072232948508 <NA>
2 2017-01-21T17:33:41Z 9.41 81 88 4.726922499738 <NA>
我已经尝试过各种关于 XPath 语法和命名空间的废话,但我得到的最接近的是
> basic2 = xmlToDataFrame(nodes <- getNodeSet(doc, "//ns:Trackpoint//ns:Extensions", "ns"))
> head(basic2,2)
TPX
1 874.68072232948508
2 884.726922499738
这当然没有改善。
谁能帮忙?
【问题讨论】:
-
结果似乎是一个数据框,所以像
head(basic,2)[,1:3]这样的东西不会只给你需要的列吗? -
不,关键是没有正确地从 XML 中提取数据——因此数据框的构造不正确。我认为您的代码会给我时间、距离和节奏,但仍然无法获得功率和速度。
-
XML 自然地更多地对应于一个列表而不是一个 data.frame,所以先将它变成一个列表可能更有用,这样您就可以重新排列它或取出您需要构建的部分数据帧。
-
@Ken,检查/编辑 - “但我不想记录扩展名(瓦特和速度)”
-
谢谢!只需要删除那个 n!