多个XML文件到R中的数据框中

时间:2017-02-13 10:35:58

标签: r xml dataframe nodes

我有155个xml文件作为数据帧导入到R中。 我对xml知之甚少,并且无法获取节点。

我想编写一个函数来获取“d2p1:KeyValueOfintEpisodesmiwmOyvC”中的所有数据

这是我的R代码:

library(XML)
xml_to_df<-function(xmlfile){
  results <- xmlParse(xmlfile)
  df <- xmlToDataFrame(nodes = getNodeSet(results, "//CardEpisodes/d2p1:KeyValueOfintEpisodesmiwmOyvC"))
  return(df)
}
my_files<-list.files(pattern="\\.xml$")
my_data<-lapply(my_files,xml_to_df)
new_df<-bind_rows(my_data)

此代码应该能够将我的工作目录中的所有xml文件组合在一起并将它们放入一个数据帧中。

我得到的错误是:

  

XPath错误:未定义的命名空间前缀
  XPath错误:Invalidexpression

我认为我的错误应该在这一行:

df <- xmlToDataFrame(nodes = getNodeSet(results, "//CardEpisodes/d2p1:KeyValueOfintEpisodesmiwmOyvC"))

我应该如何设置节点?

非常感谢你的帮助!

[编辑]

<?xml version="1.0"?>
<CPRCard xmlns="http://schemas.datacontract.org/2004/07/CPRcardViewer" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" z:Id="i1" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
   <CardEpisodes xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
      <d2p1:KeyValueOfintEpisodesmiwmOyvC>
         <d2p1:Key>0</d2p1:Key>
         <d2p1:Value>
            <AdqDepth>4</AdqDepth>
            <AdqRate>64</AdqRate>
            <AvgDepth>39</AvgDepth>
            <card z:Ref="i1"/>
         </d2p1:Value>
      </d2p1:KeyValueOfintEpisodesmiwmOyvC>

      <d2p1:KeyValueOfintEpisodesmiwmOyvC>
         <d2p1:Key>1</d2p1:Key>
            <d2p1:Value>
               <AdqDepth>17</AdqDepth>
               <AdqRate>28</AdqRate>
               <AvgDepth>45</AvgDepth>
               <card z:Ref="i1"/>
            </d2p1:Value>
      </d2p1:KeyValueOfintEpisodesmiwmOyvC>
  </CardEpisodes>
</CPRCard>

1 个答案:

答案 0 :(得分:0)

你缺少的是名称空间定义,我不是专家,但错误是“我不知道d2p1的含义”。 为避免这种情况,您必须在namespaces调用中添加getNodeSet参数:

getNodeSet(x, "//d2p1:KeyValueOfintEpisodesmiwmOyvC", 
           namespaces = c(d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays"))

我找到了在完整的xml中指定的命名空间。

无论如何只将此插入xmlToDataFrame函数会导致问题,因为节点的第一级只由KeyValue字段组成。然后,Value字段包含3个数据点。

xmlToDataFrame(nodes = getNodeSet(x,
                            "//d2p1:KeyValueOfintEpisodesmiwmOyvC", 
                             c(d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays")))
#  Key  Value
# 1   0  46439
# 2   1 172845

为了避免这种情况,我们必须进行两次不同的调用,一次是回复3个值,另一次是关键:

values <- xmlToDataFrame(nodes = getNodeSet(x,
                            "//d2p1:KeyValueOfintEpisodesmiwmOyvC/d2p1:Value",
                            c(d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays")))

keys <- xmlToDataFrame(nodes = getNodeSet(x, 
                            "//d2p1:KeyValueOfintEpisodesmiwmOyvC", 
                            c(d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays")))
# Bind and clean
result <- data.frame(Key = keys[, 1], values[, 1:3])

希望这有帮助