R语言解析法国燃油价格XML文件转列表后数据不可读问题求助
问题原因
直接将完整XML文件转换为列表时,会保留所有嵌套层级,且节点属性与子节点内容混杂,导致输出结构混乱不可读,需要针对性提取目标节点做结构化处理。
解决方案1:基于XML包实现(兼容你现有代码逻辑)
library(XML) library(data.table) # 如需输出data.table格式可加载 # 读取XML文件 xml_doc <- xmlParse("Z:/temp/PrixCarburants_annuel_2021.xml") # 提取所有加油站节点(pdv为该数据集的加油站根节点标识) pdv_nodes <- getNodeSet(xml_doc, "//pdv") # 编写单节点提取函数 extract_pdv_data <- function(node) { # 提取加油站基础属性 pdv_attr <- as.list(xmlAttrs(node)) # 提取该加油站下所有燃油价格节点 price_nodes <- getNodeSet(node, "./prix") if (length(price_nodes) == 0) { # 无价格数据的加油站返回基础信息 return(as.data.frame(c(pdv_attr, list(nom = NA, prix = NA, maj = NA)))) } # 逐行提取价格信息,和加油站基础属性合并 price_df <- do.call(rbind, lapply(price_nodes, function(p_node) { as.data.frame(as.list(xmlAttrs(p_node))) })) # 合并基础信息和价格信息 cbind(pdv_attr, price_df) } # 批量处理所有节点,合并为dataframe final_df <- do.call(rbind, lapply(pdv_nodes, extract_pdv_data)) # 如需转为data.table格式,执行以下代码即可 final_dt <- setDT(final_df)
解决方案2:基于xml2+tidyverse实现(代码更简洁易维护)
library(xml2) library(tidyverse) library(data.table) # 读取XML xml_doc <- read_xml("Z:/temp/PrixCarburants_annuel_2021.xml") # 提取所有pdv节点 pdv_nodes <- xml_find_all(xml_doc, "//pdv") # 批量提取数据 final_df <- map_dfr(pdv_nodes, function(node) { # 提取加油站属性 pdv_attr <- as.list(xml_attrs(node)) # 提取价格节点 price_nodes <- xml_find_all(node, "./prix") if (length(price_nodes) == 0) { return(as_tibble(c(pdv_attr, list(id_carburant = NA, libelle = NA, prix = NA, maj = NA)))) } # 提取价格属性合并 price_df <- map_dfr(price_nodes, ~as.list(xml_attrs(.x))) bind_cols(pdv_attr, price_df) }) # 转data.table final_dt <- setDT(final_df)
补充说明
- 输出的默认结果为长表格式,每一行对应一个加油站的某一类燃油价格,如果你需要每个加油站占一行、不同燃油价格作为列的宽表,可以用
pivot_wider函数转换 - 代码中的节点名
pdv、prix对应该开放数据集的节点定义,如果你需要提取其他节点(如加油站服务、地址等),修改对应节点提取逻辑即可
内容的提问来源于stack exchange,提问作者MonJeanJean
相关产品推荐
相关产品推荐

