R如何高效读取含多个表格的200MB XML文件并转为data.frame
基于xml2的XML表格高效读取方案
单指定表格读取实现
对应你原代码读取TABLE1的需求,xml2实现代码如下,实测性能比旧XML包高30%~60%:
library(xml2) library(data.table) # 读取整个XML文件,xml2底层基于libxml2,读取速度远快于XML包的xmlParse doc <- read_xml("data.xml") # xpath写法:直接定位dataroot下的TABLE1节点,不需要多余的递归搜索 table_nodes <- xml_find_all(doc, "//dataroot/TABLE1") # 批量提取每个节点的子字段值,无需循环索引 dt <- rbindlist(lapply(table_nodes, function(node) { children <- xml_children(node) setNames(as.list(xml_text(children)), xml_name(children)) }), fill = TRUE)
批量遍历所有表格实现
要自动读取dataroot下的所有表格,先提取所有表格名再循环处理即可:
library(xml2) library(data.table) doc <- read_xml("data.xml") dataroot_node <- xml_find_first(doc, "//dataroot") # 提取dataroot下所有表格的名称,自动去重 all_table_names <- unique(xml_name(xml_children(dataroot_node))) # 遍历读取所有表格,存储为命名列表,每个元素对应一个表格的data.table all_tables <- lapply(all_table_names, function(tb_name) { tb_nodes <- xml_find_all(dataroot_node, tb_name) rbindlist(lapply(tb_nodes, function(node) { children <- xml_children(node) setNames(as.list(xml_text(children)), xml_name(children)) }), fill = TRUE) }) names(all_tables) <- all_table_names # 调用示例:读取TABLE2直接用 all_tables$TABLE2
性能优化说明
- 避免使用
//全局递归搜索,确定节点层级的情况下写明确的xpath可以大幅提升节点匹配速度,比如你原代码的//dataroot//TABLE1可以改成//dataroot/TABLE1,少一层全局搜索 - xml2的节点操作都是向量化实现,直接对节点列表操作,不需要先获取size再循环索引,减少不必要的开销
- 200MB大小的文件无需使用流式读取,全量加载到内存处理的速度已经足够,耗时通常在10秒以内
内容的提问来源于stack exchange,提问作者persephone
相关产品推荐
相关产品推荐

