从 XML 中提取数据框(文本),但文件在 R 中具有重复的节点名称

Extract data frame (text) from XML, but file has duplicated node names in R

提问人:Sanam 提问时间:2/9/2023 更新时间:2/9/2023 访问量:39

问:

我有一个正在处理的 XML 文件,并试图让输出看起来像您在 R 中使用函数时的样子。但是,我的文件太复杂了,所以这个函数对我不起作用,并且由于节点名称重复且不唯一而给我带来错误。我附上我的 XML 文件的简化版本只是为了了解我想要实现的目标xmlToDataFrame()

<HelloWorld created="2022-03-22" id="12we">
  <myname>omi</myname>
</HelloWorld>
<HelloWorld created="2022-03-12" id="18we">
  <myh>59</myh>
  <myfname>Tom</myfname>
  <mylname>John</mylname>
</HelloWorld>
<HelloWorld created="2022-03-30" id="188yye">
  <myh>60</myh>
  <favcolor>grey</favcolor>
  <myfname>Alex</myfname>
  <mylname>Tom</mylname>
</HelloWorld>

由此,我希望生成以下输出

编号 我的姓名 马赫 myfname mylname 最喜欢的颜色
12我们 近江
18我们 59 汤姆 John
188年YYE 60 亚历克斯 汤姆 灰色

我是XML的新手,尝试了各种方法,但仍然无法正确提取数据。任何帮助将不胜感激。

R 数据帧 XML 解析

评论


答:

0赞 r2evans 2/9/2023 #1
# library(xml2)
xml <- xml2::read_html("quux.xml") |> xml2::as_list()

## either data.table or dplyr ...
out <- dplyr::bind_rows(xml$html$body)
out <- data.table::rbindlist(xml$html$body, use.names = TRUE, fill = TRUE)

out
# # A tibble: 3 × 5
#   myname    myh       myfname   mylname   favcolor 
#   <list>    <list>    <list>    <list>    <list>   
# 1 <chr [1]> <NULL>    <NULL>    <NULL>    <NULL>   
# 2 <NULL>    <chr [1]> <chr [1]> <chr [1]> <NULL>   
# 3 <NULL>    <chr [1]> <chr [1]> <chr [1]> <chr [1]>

由于 xml 的结构,所有列都是列表列。由于我们很满意所有元素的长度为 0 或 1,因此我们可以遍历所有元素以提取第一个元素:

out[] <- lapply(out, function(z) sapply(z, function(y) if (is.null(y)) NA else unlist(y)[1]))
out
# # A tibble: 3 × 5
#   myname myh   myfname mylname favcolor
#   <chr>  <chr> <chr>   <chr>   <chr>   
# 1 omi    NA    NA      NA      NA      
# 2 NA     59    Tom     John    NA      
# 3 NA     60    Alex    Tom     grey    

数据:包含内容的文件:quux.xml

<HelloWorld created="2022-03-22" id="12we">
  <myname>omi</myname>
</HelloWorld>
<HelloWorld created="2022-03-12" id="18we">
  <myh>59</myh>
  <myfname>Tom</myfname>
  <mylname>John</mylname>
</HelloWorld>
<HelloWorld created="2022-03-30" id="188yye">
  <myh>60</myh>
  <favcolor>grey</favcolor>
  <myfname>Alex</myfname>
  <mylname>Tom</mylname>
</HelloWorld>

评论

0赞 Sanam 2/10/2023
当我运行 bind_rows 或 rbindlist 时,它适用于简化的数据集,但在我的实际数据集上,我得到的输出为 0 行。你知道是什么原因造成的吗
0赞 r2evans 2/10/2023
不,我没有,您需要更新示例数据以重现 0 输出条件。也许问题出在 / 之后。使用我的代码作为模板,也许如果它不是太大,您可以提供 .read_xmlas_listdput(xml)
0赞 Sanam 2/10/2023
我认为问题在于,在实际数据中,我们有不同长度的元素,而不仅仅是长度 0 或 1。我收到以下错误:“第 1 项的第 1 列的长度为 7,与第 7 列的长度不一致,第 7 列的长度为 27。只有长度-1的色谱柱被回收”
0赞 r2evans 2/10/2023
这是将可变格式 XML 转换为刚性结构的常见问题。不幸的是,没有一个功能可以做你想做的事。当我查看此示例数据时,我曾经查看过组件,这就是我发现它可以作为起点的方式。如果你的嵌套数据有任意长度(不仅仅是你说的 0/1),那么也许看看 after ,without ,看看事情是什么样子的。同样,没有单一的解决方案,它是一个过程,它对 XML 结构太敏感而无法概括。data.framestr(xml)xml$html$bodyoutbind_rowslapply