R xml2 : 如何只查询对应的xml节点

R xml2 : How to query only corresponding xml nodes

我正在尝试读取许多 XML 文件并将其转换为 R 数据帧(或者最好是 Tibbles)。

不幸的是,当我尝试使用内置函数(例如xmltodataframe 来自 XML 包和 xml_to_df 来自 xmlconvert 包),所以我必须使用 XML2.[=13= 手动完成]

这是我的问题和一个小的工作示例:

# Minimal Working Example

library(tidyverse)
library(xml2)


interimxml <- read_xml("<Subdivision>
              <Name>Charles</Name>
              <Salary>100</Salary>
              <Name>Laura</Name>
              <Name>Steve</Name>
              <Salary>200</Salary>
              </Subdivision>")

names  <- xml_text(xml_find_all(interimxml ,"//Subdivision/Name"))
salary <- xml_text(xml_find_all(interimxml ,"//Subdivision/Salary"))

names
salary

# combine in to tibble (doesn't work because of inequal vector lengths)
result <- tibble(names=names, 
                 salary = salary)
result

rbind(names, salary)

从(编造的)XML 文件中可以看到,Charles 赚了 100 美元,Laura 什么都没赚(因为缺少条目,问题就出在这里 ) 而史蒂夫赚了 200 美元。

我想要 xml2 做的是,当查询名称和薪水节点时,当它找到一个名称时 return 一个“NA”(或者零也可以)但没有相应的工资条目,所以我最终会像这样 table:

Name Salary
Charles 100
Laura NA
Steve 200

我知道我可以修改“xpath”以仅获取最后一个值(对于史蒂夫),这对我没有帮助,因为(在实际数据中)它也可能是第 100 个或第 23 个缺少工资信息的人。

[ 我知道薪水数字是作为字符值从 xml 文件中提取的。之后我会改变(跨(薪水,as.double)列。]

非常感谢任何帮助。非常感谢您。

你需要更加小心地匹配姓名和薪水。基本上首先找到所有 <Name> 节点,然后仅检查它们的下一个兄弟是否是 <Salary> 节点。如果不是,则 return NA。

nameNodes <- xml_find_all(interimxml ,"//Subdivision/Name")
names <- xml_text(nameNodes)
salary <- map_chr(nameNodes, ~xml_text(xml_find_first(., "./following-sibling::*[1][self::Salary]")))

tibble::tibble(names, salary)
#   names   salary
#   <chr>   <chr> 
# 1 Charles 100   
# 2 Laura   NA    
# 3 Steve   200