xml2 + xml_text() 是 R 中提取 XML 文本节点最稳妥方式,需先定位记录节点、再分别用 xml_attr() 和 xml_text() 提取属性与内容,避免 xmlToDataFrame() 的结构限制与静默失败。

用 xml2 + xml_text() 提取文本节点最稳妥
直接读 XML 后转数据框,不能靠“自动猜结构”。xml2 是目前 R 中解析 XML 最可靠的基础包,它把文档当树处理,避免了老包 XML 的编码和命名空间陷阱。
常见错误是用 read_xml() 后直接丢给 as.data.frame() —— 这会把整个节点对象塞进一列,不是你想要的表格。
- 先用
xml_find_all()定位所有记录级节点(比如、、) - 对每个节点,用
xml_find_first()或xml_attr()抽字段,再用xml_text()取内容(别漏掉这个!否则返回的是节点对象) - 用
lapply()套一层,最后do.call(rbind.data.frame, ...)合并
遇到属性(attr)和子元素混用时,得分开处理
很多 XML 把元数据放属性里(如 ),这时 id 和 type 得用 xml_attr(),而 name 得用 xml_text(xml_find_first(node, "name"))。
如果强行统一用 xml_text(),属性值就拿不到;如果全用 xml_attr(),子元素内容就为空。
- 建议写一个提取函数,入参是单个记录节点,返回命名列表(
list(id = ..., name = ..., ...)) - 属性名和子元素名不要重名,否则后写的会覆盖前写的
- 用
xml_missing()判断节点是否存在,避免NA变成"character(0)"
xmlToDataFrame() 看似简单,但只适用于极简结构
来自老包 XML 的 xmlToDataFrame() 仅支持“所有叶子节点都是同级、无属性、无嵌套”的扁平 XML。比如:
1x
2y
这种能转;但只要加一个 id="r1" 属性,或嵌套一层
,它就静默失败或列错位。
- 不推荐新手用,因为报错不明确,调试成本高
- 若必须用,先用
xmlParse()读入,再确认xmlRoot(doc)下一级全是且无属性 - 返回结果列名默认是子元素名,无法自定义
中文乱码、命名空间、大文件要提前干预
用 read_xml("file.xml", encoding = "UTF-8") 显式指定编码,否则 Windows 下常出 字符。命名空间(如 xmlns="http://example.com/ns")会让 xml_find_all(x, "//item") 查不到东西——得用 xml_ns() 注册前缀,再写 //d:item。
超大 XML(>100MB)别一次性加载:用 xml_event_parse() 流式处理,或改用 Python 的 iterparse。
- 检查是否含命名空间:
xml_ns(read_xml("x.xml")),非空就得处理 - 用
xml_children()+xml_name()快速看顶层结构,别盲目写 XPath - 字段含换行或空格?
trimws(xml_text(...))必加,否则后期==匹配失效
xml_print() 瞅一眼根节点下到底有几层、哪些是 attr、哪些是 text,比硬写三遍代码更省时间。










