使用R的xmlEventParse存储特定的XML节点值

Ver*_*ica 7 sax r xml-parsing

我有一个大的XML文件,我需要在R中使用xmlEventParse进行解析.遗憾的是,在线示例比我需要的更复杂,我只想标记匹配的节点标记来存储匹配的节点文本(非属性),每个文本都在一个单独的列表中,请参阅下面代码中的注释:

library(XML)
z <- xmlEventParse(
    "my.xml", 
    handlers = list(
        startDocument   =   function() 
        {
                cat("Starting document\n")
        },  
        startElement    =   function(name,attr) 
        {
                if ( name == "myNodeToMatch1" ){
                    cat("FLAG Matched element 1\n")
                }
                if ( name == "myNodeToMatch2" ){
                    cat("FLAG Matched element 2\n")
                }
        },
        text            =   function(text) {
                if ( # Matched element 1 .... )
                    # Store text in element 1 list
                if ( # Matched element 2 .... )
                    # Store text in element 2 list
        },
        endDocument     =   function() 
        {
                cat("ending document\n")
        }
    ),
    addContext = FALSE,
    useTagName = FALSE,
    ignoreBlanks = TRUE,
    trim = TRUE)
z$ ... # show lists ??
Run Code Online (Sandbox Code Playgroud)

我的问题是,如何在R中实现这个标志(以专业的方式:)?另外:评估N个任意节点以匹配的最佳选择...如果name ="myNodeToMatchN"...节点避免大小写匹配?

my.xml可能只是一个天真的XML

<A>
  <myNodeToMatch1>Text in NodeToMatch1</myNodeToMatch1>
  <B>
    <myNodeToMatch2>Text in NodeToMatch2</myNodeToMatch2>
    ...
  </B>
</A>
Run Code Online (Sandbox Code Playgroud)

Mar*_*gan 8

我将使用fileNamefrom example(xmlEventParse)作为可重现的例子.它的标签record包含id我们想要提取的属性和文本.而不是使用handler,我会追求branches争论.这就像一个处理程序,但是可以访问整个节点而不仅仅是元素.我们的想法是编写一个闭包,它有一个位置来保存我们积累的数据,以及一个处理我们感兴趣的XML文档的每个分支的函数.所以让我们首先定义闭包 - 为了我们的目的,一个函数,返回一个函数列表

ourBranches <- function() {
Run Code Online (Sandbox Code Playgroud)

我们需要一个地方来存储我们积累的结果,选择一个环境,以便插入时间是恒定的(不是列表,我们必须追加到内存并且内存效率低)

    store <- new.env() 
Run Code Online (Sandbox Code Playgroud)

事件解析器期望在发现匹配标记时调用函数列表.我们对record标签感兴趣.我们编写的函数将接收XML文档的节点.我们想要提取一个元素id,我们将用它来存储节点中的(文本)值.我们将这些添加到我们的商店.

    record <- function(x, ...) {
        key <- xmlAttrs(x)[["id"]]
        value <- xmlValue(x)
        store[[key]] <- value
    }
Run Code Online (Sandbox Code Playgroud)

处理完文档后,我们想要一种方便的方法来检索我们的结果,因此我们为自己的目的添加一个函数,与文档中的节点无关

    getStore <- function() as.list(store)
Run Code Online (Sandbox Code Playgroud)

然后返回一个函数列表来完成闭包

    list(record=record, getStore=getStore)
}
Run Code Online (Sandbox Code Playgroud)

这里一个棘手的概念是定义函数的环境是函数的一部分,所以每次我们说ourBranches()我们得到一个函数列表一个新环境store来保持我们的结果.使用,调用xmlEventParse我们的文件,使用一组空的事件处理程序,并访问我们累积的商店.

> branches <- ourBranches()
> xmlEventParse(fileName, list(), branches=branches)
list()
> head(branches$getStore(), 2)
$`Hornet Sportabout`
[1] "18.7   8 360.0 175 3.15 3.440 17.02  0  0    3 "

$`Toyota Corolla`
[1] "33.9   4  71.1  65 4.22 1.835 19.90  1  1    4 "
Run Code Online (Sandbox Code Playgroud)