htmlTreeParse处理程序说明

时间:2014-08-09 00:13:21

标签: r

XML包中的?htmlParse 示例 部分中,有以下函数getLinks()

getLinks <- function() { 
       links <- character() 
       list(a = function(node, ...) { 
                   links <<- c(links, xmlGetAttr(node, "href"))
                   node 
                }, 
            links = function()links)
     }

使用它之后,然后盯着它看了一会儿,我仍然无法绕过函数体内发生的事件序列。

> bod <- as.list(body(getLinks))
> c(bod, rapply(bod, as.list))
[[1]]
`{`

[[2]]
links <- character()

[[3]]
list(a = function(node, ...) {
    links <<- c(links, xmlGetAttr(node, "href"))
    node
}, links = function() links)

$a
function (node, ...) 
{
    links <<- c(links, xmlGetAttr(node, "href"))
    node
}
<environment: 0x595f7f0>

$links
function () 
links
<environment: 0x595f7f0>

有人可以提供此功能中发生的事件链的详细说明吗?

对于示例,请运行以下代码:

> library(XML)
> URL <- "http://www.retrosheet.org/game.htm"
> h1 <- getLinks()
> htmlTreeParse(URL, handlers = h1)
> h1$links()

2 个答案:

答案 0 :(得分:8)

就它自己来说,这个功能真的没什么用。它实际上只在htmlTreeParse的上下文中有用。它做的是两件事。首先,它创建一个机箱/环境,其中将收集链接向量。其次,它返回一个列表,可以在handler=中用作htmlTreeParse。根据文档,处理程序是

  

用于将不同XML节点映射到R对象的可选函数集合。通常,这是一个命名的函数列表,闭包可用于提供本地数据。这提供了一种过滤树在R中创建,添加或删除节点的方法,并且通常在C代码中构造它们时对它们进行处理。

因此htmlTreeParse将在列表中查找与HTML文件中元素的节点名称匹配的名称。因此,由于列表具有“a”元素,因此将为文档中的每个<a>(链接)标记调用该函数。该函数只提取存储URL的href属性,并将其添加到机箱中的links数组中。

最后,解析完成后,您需要一种方法来访问闭包内的links向量。因此该列表还定义了“链接”元素。这是一个只返回受保护矢量的函数。只要它与HTML文档中的标记名称不匹配,您就可以调用此函数。

所以这个getLinks()函数只返回一个可以用作处理程序的列表。大多数实际工作都是在htmlTreeParse函数中完成的。

答案 1 :(得分:2)

除了对Flick先生的出色解释之外,这里还简单演示了这个功能是如何工作的:

 getLinks <- function() { 
  links <- character() 
  list(a = function(node, ...) { 
    links <<- c(links,  node)  ## I omit the call to XMLGetAttr
    node 
  }, 
  links = function()links)
}
h1 = getLinks()

现在我只是多次调用该函数,并在每次调用时打印结果链接:

for (i in 1:3 ){
  print(h1$links())
  h1$a(paste0("node",i))
}

如您所见,链接只是一个列表,在每次调用getlinks时会被找到的新链接增加:

character(0)
[1] "node1"
[1] "node1" "node2"