使用xpathApply的空列表

时间:2014-01-27 03:35:47

标签: xml r list xpath

我正在尝试解析Garmin 500文件中的信息。我已成功读入数据:

data <- xmlInternalTreeParse("C:/Users/Ryan Caldwell/Documents/1_26_2014 11_04_29 AM_history.tcx", useInternalNodes=T) 

但是在我使用xpathApply函数后,我收到了:

 x <- xpathApply(data, "/TrainingCenterDatabase//Calories", xmlValue)
> x
list()

这是一些文件的样子:

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<TrainingCenterDatabase xmlns=http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2 xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance xsi:schemaLocation=http://www.garmin.com/xmlschemas/ActivityExtension/v2 http://www.garmin.com/xmlschemas/ActivityExtensionv2.xsd http://www.garmin.com/xmlschemas/FatCalories/v1 http://www.garmin.com/xmlschemas/fatcalorieextensionv1.xsd http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2 http://www.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd">

  <Activities>
    <Activity Sport="Biking">
     <Id>2014-01-26T17:04:29Z</Id>
     <Lap StartTime="2014-01-26T17:04:29Z">
       <TotalTimeSeconds>1104.6240000</TotalTimeSeconds>
       <DistanceMeters>8046.7397461</DistanceMeters>
       <MaximumSpeed>12.2260008</MaximumSpeed>
       <Calories>170</Calories>
       <AverageHeartRateBpm xsi:type="HeartRateInBeatsPerMinute_t">
         <Value>122</Value>
       </AverageHeartRateBpm>
       <MaximumHeartRateBpm xsi:type="HeartRateInBeatsPerMinute_t">
         <Value>148</Value>
       </MaximumHeartRateBpm>
       <Intensity>Resting</Intensity>
       <TriggerMethod>Distance</TriggerMethod>

为什么列表中没有任何内容?

2 个答案:

答案 0 :(得分:1)

这里有几个问题。

首先,您的示例x​​ml文件格式错误。除了你遗漏了一些结束标记这一事实之外,名称空间URI必须用引号括起来,例如:

xmlns="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2"

xmlns=http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2

按原样,我无法理解如何首先加载文档。

其次(一旦上述问题得到解决),@ har07基本上是正确的。由于您声明了默认命名空间,因此必须在xPath中引用它。不幸的是,仅使用ns:不起作用:

x <- xpathApply(data, "/ns:TrainingCenterDatabase//ns:Calories", xmlValue)
# XPath error : Undefined namespace prefix
# XPath error : Invalid expression
# Error in xpathApply.XMLInternalDocument(data, "/ns:TrainingCenterDatabase//ns:Calories",  : 
#   error evaluating xpath expression /ns:TrainingCenterDatabase//ns:Calories

相反,您必须将ns声明为xpathApply调用中的默认命名空间,如下所示:

ns <- c(ns="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2")
x  <- xpathApply(data, "/ns:TrainingCenterDatabase//ns:Calories", xmlValue, namespaces=ns)
x
# [[1]]
# [1] "170"

上面的第一行创建了一个带有一个元素ns的命名向量,其中包含默认命名空间的URI。现在,使用ns:Calories(等)将起作用。

最后,您可以使用更简单的xPath字符串并获得相同的结果:

x <- xpathApply(data, "//ns:Calories", xmlValue, namespaces=ns)

答案 1 :(得分:0)

由于发布的样本XML具有默认名称空间,我建议尝试为XPath查询提供名称空间前缀。像这样:

x <- xpathApply(data, "/ns:TrainingCenterDatabase//ns:Calories", namespaces = c(ns = "http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2"))

[Reference]

不确定上面是否是正确的语法,我对一无所知。但是这个概念是(在我的理解中,CMIIW),当XPath查询中没有提供前缀时,它将被视为没有命名空间的元素。在XML中,当文件声明了默认名称空间时,所有没有前缀的元素都将被视为默认名称空间。

更新:

微小的修复。基于@jlhoward,回答我上面缺少一个参数xmlValue的示例代码段。它应该是:

x <- xpathApply(data, "/ns:TrainingCenterDatabase//ns:Calories", xmlValue, namespaces = c(ns = "http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2"))