5

我有一个巨大的 xml 文件(260mb),其中包含大量信息,如下所示:

例子:

<mydocument>
<POSITIONS EventTime="2012-09-29T20:31:21" InternalMatchId="0000T0">
<FrameSet GameSection="1sthalf" Match="0000T0" Club="REFEREE" Object="00011D">
<Frame N="0" T="2012-09-29T18:31:21" X="-0.1158" Y="0.2347" S="1.27" />
<Frame N="1" T="2012-09-29T18:31:21" X="-0.1146" Y="0.2351" S="1.3" />
<Frame N="2" T="2012-09-29T18:31:21" X="-0.1134" Y="0.2356" S="1.33" />
</FrameSet>
<FrameSet GameSection="2ndhalf" Match="0000T0" Club="REFEREE" Object="00011D">
<Frame N="0" T="2012-09-29T18:31:21" X="-0.1158" Y="0.2347" S="1.27" />
<Frame N="1" T="2012-09-29T18:31:21.196" X="-0.1146" Y="0.2351" S="1.3" />
<Frame N="2" T="2012-09-29T18:31:21.243" X="-0.1134" Y="0.2356" S="1.33" />
</FrameSet>
</POSITIONS>
</mydocument>

大约有 40 个不同的 FrameSet 节点,每个节点都有不同的GameSection="..."Object="...".

我很想将<Frame>节点的信息提取到一个list对象中,但我无法加载整个 xml 文件,因为它太大了。有什么办法,我可以使用该xmlEventParse函数过滤特定的GameSection和特定的Object并从相应的<Frame>元素中获取所有信息?

4

1 回答 1

8

可能是“内部”表示并没有那么大

xml = xmlTreeParse("file.xml", useInternalNodes=TRUE)

然后 xpath 肯定是你最好的选择。如果这不起作用,您将需要考虑关闭。我的目标是 的branches参数xmlEventParse,它允许混合事件解析遍历文件,再加上每个节点上的 DOM 解析。这是一个返回函数列表的函数。

branchFactory <-
    function()
{
    env <- new.env(parent=emptyenv())   # safety

    FrameSet <- function(elt) {
        id <- paste(xmlAttrs(elt), collapse=":")
        env[[id]] <- xpathSApply(elt, "//Frame", xmlAttrs)
    }

    get <- function() env

    list(get=get, FrameSet=FrameSet)
}

在这个函数中,我们将创建一个地方来存储我们遍历文件时的结果。这可能是一个列表,但使用环境会更好。这将允许我们插入新结果,而无需复制我们已经插入的所有结果。所以这是我们的环境:

    env <- new.env(parent=emptyenv())

我们使用该parent论点作为安全性的衡量标准,即使它与我们目前的案例无关。现在我们定义一个每当遇到“FrameSet”节点时都会调用的函数

    FrameSet <- function(elt) {
        id <- paste(xmlAttrs(elt), collapse=":")
        env[[id]] <- xpathSApply(elt, "//Frame", xmlAttrs)
    }

事实证明,当我们使用branches参数时,xmlEventParse将安排将整个节点解析为我们可以通过 DOM 操作的对象,例如使用xlmAttrsand xpathSApply。这个函数的第一行为这个框架集创建了一个唯一标识符(?也许整个数据集不是这种情况?你需要一个唯一标识符)。然后我们解析元素的“//Frame”部分,并将其存储在我们的环境中。存储结果比看起来要复杂——我们分配给一个名为env. envFrameSet 函数的主体中不存在,因此 R 使用其词法范围规则来搜索在定义envFrameSet 函数的环境中命名的变量。瞧,它发现env我们已经创建了。这是我们添加 to 的结果的地方xpathSApply。这就是我们的 FrameSet 节点解析器。

我们还想要一个可以用来检索的便捷函数env,如下所示:

    get <- function() env

同样,这将使用词法范围来查找envbranchFactory. 我们最后branchFactory返回我们定义的函数列表

    list(get=get, FrameSet=FrameSet)

这也非常棘手——我们返回了一个函数列表。这些函数是在我们调用时创建的环境中定义的branchFactory,为了使词法作用域起作用,环境必须保持不变。所以实际上我们不仅返回了函数列表,还隐含地返回了变量env。简单来说

我们现在准备解析我们的文件。通过创建一个分支解析器的实例来做到这一点,它具有自己独特的getandFrameSet函数版本以及env为存储结果而创建的变量。然后解析文件

b <- branchFactory()
xx <- xmlEventParse("file.xml", handlers=list(), branches=b)

我们可以使用 检索结果b$get(),如果方便的话,可以将其转换为列表。

> as.list(b$get())
$`1sthalf:0000T0:REFEREE:00011D`
  [,1]                  [,2]                  [,3]                 
N "0"                   "1"                   "2"                  
T "2012-09-29T18:31:21" "2012-09-29T18:31:21" "2012-09-29T18:31:21"
X "-0.1158"             "-0.1146"             "-0.1134"            
Y "0.2347"              "0.2351"              "0.2356"             
S "1.27"                "1.3"                 "1.33"               

$`2ndhalf:0000T0:REFEREE:00011D`
  [,1]                  [,2]                      [,3]                     
N "0"                   "1"                       "2"                      
T "2012-09-29T18:31:21" "2012-09-29T18:31:21.196" "2012-09-29T18:31:21.243"
X "-0.1158"             "-0.1146"                 "-0.1134"                
Y "0.2347"              "0.2351"                  "0.2356"                 
S "1.27"                "1.3"                     "1.33"                   
于 2013-05-22T00:47:15.940 回答