使用 xml2 提取子节点而不丢失与父节点的连接

Extract child nodes without losing connection to the parent using xml2

假设我有以下 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>'))

我可以遍历它以访问单个 <item> 个节点中的 <link> 个节点。

lapply(x, xml_find_all, xpath = "link")

这会生成一个单独的节点集列表,让我知道哪个“链接”集合属于哪个“项目”。但是遍历一个较长的节点集(比如数千个 <item> 节点)可能会很慢。

相比之下,下面的链接几乎是即时的(我认为更接近应该如何使用 xml2 的精神)但我不再知道链接来自哪个项目。他们似乎都是兄弟姐妹:

xml_find_all(x, xpath = "link")

问题:如何在不丢失有关 <item> 节点的信息的情况下提取 <link> 节点,从而避免上面的 lapply 解决方案?

对于每个 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")
)