如何使用xml2包将数据帧转换为xml?

时间:2017-08-28 20:50:25

标签: r xml xml2

我正在尝试使用xml2使用新节点更新xml文件。如果我只是手动将所有内容写成文本

,这很容易
oldXML <- read_xml("<Root><Trial><Number>3.14159 </Number><Adjective>Fast </Adjective></Trial></Root>")

但是我正在开发一个运行计算的应用程序,然后将这些值放入xml中,所以我需要混合使用字符和变量。它最终看起来像:

var1 <- 4.567
var2 <- "Slow"
newLine <- read_xml(paste0("<Trial><Number>",var1," </Number><Adjective>",var2," </Adjective></Trial>"))
xml_add_child(oldXML,newLine)

我怀疑使用paste0的方法比使用paste0要少得多,但是我无法使用其他任何东西。我希望能够通过引用数据框来指示它更新xml,以便它可以创建新的试验:

<Trial>
  <Number>df$number[1]</Number>
  <Adjective>df$adjective[1]</Adjective>
</Trial>
<Trial>
  <Number>df$number[2]</Number>
  <Adjective>df$adjective[2]</Adjective>
</Trial>

有没有办法以这种方式创建新的试验节点,或者至少比使用paste0插入变量更自然?这是XML包比xml2更好吗?

2 个答案:

答案 0 :(得分:3)

如果您在data.frame中有新值,请执行以下操作:

vars <- data.frame(Number = c(4.567, 3.211),
                   Adjective = c("Slow", "Slow"),
                   stringsAsFactors = FALSE)

您可以将其转换为xml_document的列表,如下所示:

vars_xml <- lapply(purrr::transpose(vars),
                   function(x) {
                       as_xml_document(list(Trial = lapply(x, as.list)))
                   })

然后您可以将新节点添加到原始xml:

for(trial in vars_xml) xml_add_child(oldXML, trial)

我不知道这比你的paste方法更好。无论哪种方式,您都可以将它包装在一个函数中,这样您只需编写一次丑陋的代码。

答案 1 :(得分:1)

这是基于@Ista出色答案的解决方案。基本上,我放弃了第一个lapply来支持purrr::map(我们可以用lapply来替换第二个map,但是我找不到更易读的的方式)。

library(purrr)

vars_xml <- transpose(vars) %>% 
   map(~as_xml_document(list(Trial = lapply(.x, as.list))))