我有很多非常大(> 10GB)的xml文件,格式如下:
<?xml version="1.0" encoding="UTF-8"?>
<records xmlns="http://website”>
<REC rid=“this is a test”>
<UID>ABCD123</UID>
<data_1>
<fullrecord_metadata>
<references count=“2”>
<reference>
<uid>ABCD2345</uid>
</reference>
<reference>
<uid>ABCD3456</uid>
</reference>
</references>
</fullrecord_metadata>
</data_1>
</REC>
<REC rid=“this is a test”>
<UID>XYZ0987</UID>
<data_1>
<fullrecord_metadata>
<references count=“N”>
</references>
</fullrecord_metadata>
</data_1>
</REC>
</records>
目标是创建如下数据集:
str_UID str_ref str_tot
ABCD123 ABCD2345 2
ABCD123 ABCD3456 2
XYZ0987 NULL N
其中所有变量都是字符串。
棘手的部分是提取“2”和“N”,将它们保存为字符串。
从上一篇文章(链接)中,我能够使用以下代码生成前两行,该代码依赖 xmlEventParse 直接通过 xpathSApply 读取元素,而无需将 xml 文件加载到内存(这对于完整数据不可行) :
uid_traverse <- function() {
uids <- ""
refs <- ""
REC <- function(x) {
uid <- xpathSApply(x, "//UID", xmlValue)
ref <- xpathSApply(x, "//reference/uid", xmlValue)
if (length(uid) > 0) {
if (length(var) == 0) {
uids <<- c(uids, uid)
refs <<- c(refs, NA_character_)
} else {
uids <<- c(uids, rep(uid, length(ref)))
refs <<- c(refs, ref)
}
}
}
list(
REC = REC,
uid_df = function() {
data.frame(uid = uids, ref = refs, stringsAsFactors = FALSE)
}
)
}
uid_f <- uid_traverse()
invisible(
xmlEventParse(
file = path.expand(url),
branches = uid_f["REC"])
)
DF <- do.call(cbind.data.frame, uid_f$uid_df())
但是,由于我感兴趣的数据——这里的“2”和“N”——包含在标签括号 <> 中,我不知道如何修改 xpathSApply 或 xmlEventParse 来提取这些字符串。
注意:真正的数据设置是这些值不仅仅是子元素中包含的信息的计数,而是标识码,所以我必须直接提取它们,而不是从子元素的数量等中推断出来。