用 xml2::read_xml() 读远程 xml 失败,主因常是网络请求异常或响应非 xml;应先用 httr::get() 检查状态码与 content_type,处理重定向、gzip、bom 及编码问题。

用 xml2::read_xml() 读取远程 XML 文件失败?先检查网络和编码
直接用 xml2::read_xml("https://example.com/data.xml") 报错“Failed to parse XML”或“Connection refused”,大概率不是解析问题,而是请求没发出去或返回了非 XML 内容。Web 上的 XML 响应常带重定向、认证头、gzip 压缩或 UTF-8 BOM,xml2::read_xml() 默认不处理这些。
- 先用
httr::GET()手动发请求,检查status_code和content_type,确认返回的是text/xml或application/xml - 若响应含 gzip(
Content-Encoding: gzip),需加httr::config(accept_encoding = "gzip"),否则read_xml()会解包失败 - 某些站点返回带 BOM 的 UTF-8,
read_xml()可能卡在开头字节,此时用rawToChar(httr::content(r, as = "raw"))提取原始内容再传给xml2::read_xml()
xml2::xml_find_all() 找不到节点?路径写法和命名空间是关键
明明 XML 里有 <item><title>Hello</title></item>,但 xml_find_all(doc, "//title") 返回空,常见原因是文档含默认命名空间(如 xmlns="http://purl.org/rss/1.0/")——XPath 默认不匹配带命名空间的节点。
- 用
xml_ns(doc)查看是否存在命名空间;若有,必须显式声明前缀,例如xml_find_all(doc, "//rss:title", ns = xml_ns(doc)) -
//是深度优先搜索,性能差;如果结构固定,优先用绝对路径如/rss/channel/item/title - 节点名区分大小写,
"TITLE"和"title"不等价;属性要用@attr,比如//item[@id="123"]
把 XML 转成数据框时字段错位?别硬套 xml2::as_list()
xml2::as_list() 会把嵌套结构转成深层 list,直接 as.data.frame() 往往崩:列长度不一致、类型混杂、重复字段丢失。RSS 或 Atom 这类扁平化重复节点(多个 <item></item>)才适合转数据框。
本文档主要讲述的是使用JSON进行网络数据交换传输;JSON(JavaScript ObjectNotation)是一种轻量级的数据交换格式,易于阅读和编写,同时也易于机器解析和生成,非常适合于服务器与客户端的交互。JSON采用与编程语言无关的文本格式,但是也使用了类C语言的习惯,这些特性使JSON成为理想的数据交换格式。 和 XML 一样,JSON 也是基于纯文本的数据格式。由于 JSON 天生是为 JavaScript 准备的,因此,JSON的数据格式非常简单,您可以用 JSON 传输一个简单的 St
- 对重复节点,用
xml_find_all()先提取所有<item></item>,再对每个节点分别提取子字段,最后用lapply()+xml_text()组合成 list-of-lists - 字段值为空时
xml_text()返回空字符串,但xml_attr()取不到属性会返回NULL,需统一用xml_attr(x, "attr", default = NA)避免长度错乱 - 时间字段常为 ISO 格式字符串,别在 XML 层面转
POSIXct,留到数据框生成后用lubridate::ymd_hms()处理更稳
中文乱码或特殊字符显示为 ?XML 声明和 R 会话编码要对齐
即使 XML 文件头部写了 <?xml version="1.0" encoding="UTF-8"?>,R 读入后仍可能显示方块或问号,根本原因是 R 的本地编码设置(Sys.getlocale("LC_CTYPE"))与实际内容不一致,尤其在 Windows 上默认是 GBK。
- Linux/macOS 一般没问题;Windows 用户务必在脚本开头加
Sys.setlocale("LC_CTYPE", "Chinese")或"en_US.UTF-8"(取决于系统支持) - 用
xml2::read_xml()时加参数encoding = "UTF-8"强制指定,比依赖 XML 声明更可靠 - 如果已读入乱码对象,别试图用
iconv()补救——xml2内部用 raw 处理,乱码后信息已损,必须重新read_xml()
真正麻烦的是混合编码的旧系统 XML(比如部分字段 GBK、部分 UTF-8),这种没有通用解法,得先用二进制读取、按节点切分、逐段检测编码再解析——属于边界情况,日常遇到就该推动上游统一输出 UTF-8。









