使用R的xmlEventParse存储XML节点值以用于过滤输出

我有一个巨大的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>的信息.节点到列表对象但我无法加载整个xml文件,因为它太大了.有什么办法,我可以使用xmlEventParse函数来过滤特定的GameSection和一个特定的Object,并从相应的< Frame>获取所有信息.元素?

最佳答案
可能是“内部”表示并不那么大

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

然后xpath绝对是你最好的选择.如果这不起作用,你需要关闭闭合.我将针对xmlEventParse的branches参数,它允许混合事件解析迭代文件,并在每个节点上进行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())

我们使用父参数作为安全措施,即使它与我们目前的情况无关.现在我们定义一个函数,只要遇到“FrameSet”节点就会调用该函数

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

事实证明,当我们使用branches参数时,xmlEventParse将安排将整个节点解析为我们可以通过DOM操作的对象,例如,使用xlmAttrs和xpathSApply.此函数的第一行为此框架集创建唯一标识符(?可能不是完整数据集的情况?您需要一个唯一标识符).然后我们解析元素的“// Frame”部分,并将其存储在我们的环境中.存储结果比看起来更棘手 – 我们将分配给一个名为env的变量. env不存在于FrameSet函数的主体中,因此R使用其词法作用域规则在定义了FrameSet函数的环境中搜索名为env的变量.而且,它找到了我们已经创造的环境.这是我们将xpathSApply的结果添加到的地方.这就是我们的FrameSet节点解析器.

我们也喜欢一个方便功能,我们可以用它来检索env,如下所示:

    get <- function() env

同样,这将使用词法作用域来查找在branchFactory顶部创建的env变量.我们通过返回我们定义的函数列表来结束branchFactory

    list(get=get, FrameSet=FrameSet)

这也是非常棘手的 – 我们正在返回一系列功能.这些函数在我们调用branchFactory时创建的环境中定义,并且为了使词法范围起作用,环境必须保持不变.所以实际上我们不仅返回函数列表,而且隐含地返回变量env.简单来说

我们现在准备解析我们的文件了.通过创建分支解析器的实例来执行此操作,使用它自己的get和FrameSet函数的唯一版本以及为存储结果而创建的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"                   

转载注明原文:使用R的xmlEventParse存储XML节点值以用于过滤输出 - 代码日志