You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 19:12:01