问题描述
假设我具有以下XML:
library(xml2)
x = xml_children(read_xml('<?xml version="1.0" encoding="UTF-8"?>
<items>
<item type="greeting" id="9273938">
<link type="1" id="139" value="Hi"/>
<link type="1" id="142" value="Hello"/>
<link type="1" id="130" value="Ahoy"/>
</item>
<item type="greeting" id="9225694">
<link type="1" id="138" value="Bye"/>
<link type="1" id="131" value="Adios"/>
</item>
</items>'))
我可以遍历它以访问各个<link>
节点中的<item>
个节点。
lapply(x,xml_find_all,xpath = "link")
这将产生一个单独的节点集的列表,这使我可以知道“链接”的哪个集合属于哪个“项目”。但是,在冗长的节点集(例如数千个<item>
节点)上循环会很慢。
相比之下,以下内容几乎是即时的(我认为更接近应如何使用xml2的精神),但我不再知道链接来自哪个项目。他们似乎都是兄弟姐妹:
xml_find_all(x,xpath = "link")
问题:如何提取<link>
个节点而不会丢失有关它们来自的<item>
的信息,从而避免上述不受欢迎的解决方案?
解决方法
对于每个link
节点,您可以通过/parent::item
获取有关父项的信息:
library(xml2)
x <- read_xml('<?xml version="1.0" encoding="UTF-8"?>
<items>
<item type="greeting" id="9273938">
<link type="1" id="139" value="Hi"/>
<link type="1" id="142" value="Hello"/>
<link type="1" id="130" value="Ahoy"/>
</item>
<item type="greeting" id="9225694">
<link type="1" id="138" value="Bye"/>
<link type="1" id="131" value="Adios"/>
</item>
</items>')
links <- x %>% xml_find_all("//link")
data.frame(
item_id = links %>% xml_find_first("./parent::item") %>% xml_attr("id"),# notice the dot refers to the current link node
link_id = links %>% xml_attr("id"),value = links %>% xml_attr("value")
)