如何在R中指定父节点row解析嵌套XML为DataFrame?
嵌套XML转DataFrame的列重复错误解决方法
问题背景
使用R的XML包解析嵌套XML时,直接调用xmlToDataFrame()会导致列包含整个节点内容;指定父节点row后又触发列重复下标错误:
Error in
[<-.data.frame(*tmp*, i, names(nodes[[i]]), value = c(row = "41021206Frankford2NORTHEASTERN", : duplicate subscripts for columns
初始代码:
require(XML) data <- xmlInternalTreeParse("test2.xml") df <- xmlToDataFrame(data)
尝试修正的代码:
df <- xmlToDataFrame(nodes=getNodeSet(data, "//row"))
错误原因
你的XML结构中,row节点下存在同名子节点(比如重复的标签名),xmlToDataFrame无法自动处理重复列名,因此抛出错误。
解决方案
方法1:手动提取节点内容构建DataFrame
遍历每个row节点,手动提取所需子节点的文本值,规避重复列名问题:
require(XML) data <- xmlInternalTreeParse("test2.xml") rows <- getNodeSet(data, "//row") # 替换为你的XML中实际需要提取的子节点名称 target_nodes <- c("id", "name", "region") # 遍历每个row,提取对应节点的文本值 df_list <- lapply(rows, function(row) { sapply(target_nodes, function(node) { xmlValue(getNodeSet(row, paste0("./", node))[[1]]) }) }) # 转换为DataFrame df <- as.data.frame(do.call(rbind, df_list), stringsAsFactors = FALSE)
方法2:用xmlToList预处理后整理
先将XML转为列表,再通过数据框整理函数处理重复项:
require(XML) data <- xmlInternalTreeParse("test2.xml") row_list <- xmlToList(data)[["row"]] # 假设根节点下直接包含row节点 # 处理列表中的重复元素,转为数据框 df <- as.data.frame(do.call(rbind, lapply(row_list, function(x) { # 若有重复键,这里示例取第一个值,可根据需求改为合并等逻辑 sapply(names(x), function(n) x[[n]][1]) })), stringsAsFactors = FALSE)
方法3:使用xml2包(替代XML包,更灵活)
如果可以切换工具包,xml2配合tidyverse生态处理嵌套XML更便捷:
require(xml2) require(dplyr) require(tidyr) data <- read_xml("test2.xml") df <- data %>% xml_find_all("//row") %>% map_df(function(row) { tibble( id = row %>% xml_find_first("./id") %>% xml_text(), name = row %>% xml_find_first("./name") %>% xml_text(), region = row %>% xml_find_first("./region") %>% xml_text() # 根据你的XML结构添加更多字段 ) })
内容的提问来源于stack exchange,提问作者Youssef
相关产品推荐
相关产品推荐

