R语言基于xml2提取XML查询返回全部时间序列的高效方案
问题原因
你用xml2::as_list()直接转换整个XML文档后没有遍历嵌套结构,才会误以为只返回了一个时间序列。该接口返回的XML里所有时间序列都存放在同级的TimeSeries节点下,直接转列表后需要逐层提取,用XPath定位节点的处理效率更高。
解决代码
library(xml2) library(dplyr) library(purrr) # 原有基础配置 url.iscb <- "http://www.sedlabanki.is/xmltimeseries/" d.all <- as.Date("1990-01-01") d.now <- Sys.Date() u <- paste0(url.iscb,"Default.aspx?DagsFra=",d.all,"T00%3a00%3a00&DagsTil=", d.now,"T23%3a59%3a59&GroupID=1&Type=xml") # 读取XML f <- read_xml(u) # 1. 定位所有时间序列节点 ts_nodes <- xml_find_all(f, "//TimeSeries") # 2. 批量提取所有时间序列,合并为一个数据框 iscb.rates <- map_dfr(ts_nodes, function(ts_node) { # 提取当前时间序列的基础信息 ts_id <- xml_text(xml_find_first(ts_node, "./Id")) ts_name <- xml_text(xml_find_first(ts_node, "./Name")) # 提取该序列下所有数据条目 entry_nodes <- xml_find_all(ts_node, "./Entry") map_dfr(entry_nodes, function(entry) { data.frame( series_id = ts_id, series_name = ts_name, date = as.Date(xml_text(xml_find_first(entry, "./Date"))), value = as.numeric(xml_text(xml_find_first(entry, "./Value"))), stringsAsFactors = FALSE ) }) })
代码说明
- 用
xml_find_all(f, "//TimeSeries")直接定位所有时间序列根节点,避免手动解析嵌套列表 - 用purrr的
map_dfr批量迭代所有节点,自动合并为数据框,不需要提前初始化空数据框拼接 - 每个时间序列的ID、名称会和对应数据条目绑定,方便后续筛选单独的时间序列使用
- 如果不需要保留序列ID和名称,只需后续按需求筛选列即可
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

