在R中指定xpathSApply

时间:2014-08-26 17:54:17

标签: xml r function line-breaks sapply

我不是R-pro,只是一个谦虚的用户将不同的信息合并到一个符合我需要的脚本中。可悲的是,我解决了一个我无法解决的问题,这就是我来到这里的原因:

我想将来自许多XML文件的数据放入一个数据框中。现在,其中一个变量/列(从特定节点中提取)非常大(许多文本包含许多换行符等)。在解析XML并将提取的信息强制转换为df(将其写入带有制表符分隔符的.txt文件)时,R将这一个大变量写为不是一列,这使得无法将输出作为数据帧处理。

现在,为了解决这个难题,我想插入像

这样的东西
gsub("[\t\n]", "", xmlValue)

作为第六个xpathSApply函数的参数来摆脱换行符。 如何整合?或者还有另一个答案吗?

到目前为止,这是我的代码:

rm(list = ls())
setwd("L:/.../testfiles")
library(XML)

list.files(path = ".", pattern = NULL, all.files = FALSE,
       full.names = FALSE, recursive = FALSE,
       ignore.case = FALSE, include.dirs = FALSE, no.. = FALSE)

files <- dir(path = ".", pattern = NULL, all.files = FALSE,
         full.names = FALSE, recursive = FALSE,
         ignore.case = FALSE, include.dirs = FALSE, no.. = FALSE) 

for(i in 1:2){

tryCatch({

motion <- xmlParse(files[i]) 
root <- xmlRoot(motion)


frame <- data.frame(
  "." = xpathSApply(root, "//dokument/datum", xmlValue),
  "." = xpathSApply(root, "//dokument/subtyp", xmlValue),
  "." = xpathSApply(root, "//dokument/titel", xmlValue),
  "." = xpathSApply(root, "//dokument/subtitel", xmlValue),
  "." = xpathSApply(root, "//dokintressent//namn", xmlValue),
  "." = xpathSApply(root, "//dokument/html", xmlValue),       ## <- the huge node
  check.names=FALSE, check.rows=FALSE)

colnames(frame)[1] <- "" 
colnames(frame)[2] <- ""
colnames(frame)[3] <- ""
colnames(frame)[4] <- ""
colnames(frame)[5] <- ""
colnames(frame)[6] <- ""


write.table(frame, "L:/.../Satz.txt", 
            sep="\t", append=TRUE, na="NA", row.names=FALSE)

}, error=function(e){cat("ERROR :",conditionMessage(e), "\n")})

}

示例数据:2个文件(我不允许发布更多内容 - 只需点击链接并选择“慢速下载”)。 http://speedy.sh/S2JsU/modifiedFile1.xml http://speedy.sh/Ce2Jg/modifiedFile2.xml

我真的希望解决这个问题的方式与我看来一样困难,而且我不必为在这个崇高的社区面前提出这个问题而感到羞耻。

非常感谢你们!

CH

1 个答案:

答案 0 :(得分:0)

如果您不提供reproducible example样本输入数据来测试可能的解决方案,那将很困难。但是如何定义新的辅助函数

xmlCleanValue <-function(x) {
    gsub("[\t\n]", "", xmlValue(x))
}

然后像

一样使用它
xpathSApply(root, "//dokument/html", xmlCleanValue)