每个节点可以抓取多个值



以XML为例

<body>
  <items>
    <item>
      <name>Peter</name>
    </item>
  </items>
  <items>
    <item>
      <name>Paul</name>
    </item>
    <item>
      <name>Claudia</name>
    </item>
  </items>
  <items/>
</body> 

问题:得到下列结果最简单的方法是什么?

"Peter"   "Paul"   ""

现在我实现如下:

require(rvest)
require(magrittr)
my_xml <- xml("<items><item><name>Peter</name></item></items><items><item><name>Paul</name></item><item><name>Claudia</name></item></items><items></items>")
items <- my_xml %>% xml_nodes("items") %>% xml_node("item")
sapply(items, function(x){
  if(is.null(x)){
    ""
  } else {
    x %>% xml_node("name") %>% xml_text()
  }
})

对我来说,这个sapply结构看起来像是滥用rvest或css-selector。

rvest真的不需要,因为这是纯XML(你最终使用xml2结构无论如何):

library(xml2)
doc <- read_xml("<body>
  <items>
    <item>
      <name>Peter</name>
    </item>
  </items>
  <items>
    <item>
      <name>Paul</name>
    </item>
    <item>
      <name>Claudia</name>
    </item>
  </items>
  <items/>
</body>")

sapply(xml_find_all(doc, "//items"), function(x) {
  val <- xml_text(xml_find_all(x, "./item[1]/name"))
  ifelse(length(val)>0, val, "")
})
## [1] "Peter" "Paul"  ""     

(有时XPath比CSS更好)

相关内容

  • 没有找到相关文章

最新更新