首页 > 解决方案 > R 库“XML”无法识别编码

问题描述

问题

我有一个我想在 R 中解析的 XML 文件。我知道这个文件没有损坏,因为以下 Python 代码似乎可以工作:

>>> import xml.etree.ElementTree as ET
>>> xml_tree = ET.parse(PATH_TO_MY_XML_FILE)
>>> do_my_regular_xml_stuff_that_seems_to_work_no_problem(xml_tree)

现在,当我尝试在 R 中运行以下代码时,我收到一条错误消息:

> library("XML")
> xml_tree <- XML::xmlParse(PATH_TO_MY_XML_FILE)

Error in nchar(text_repr): invalid multibyte string, element 1
Traceback:


好吧,也许解析器无法识别编码。幸运的是,这应该在一个体面的 XML 文件中指定。所以,我去我的 shell 并检查:

$ head -n1 PATH_TO_MY_XML_FILE

??<?xml version="1.0" encoding="utf-16"?>

现在,我可以回到 R 并显式传递编码,只是面对我现在卡住的下一条错误消息:

> library("XML")
> xml_tree <- XML::xmlParse(PATH_TO_MY_XML_FILE, encoding='UTF-16')

Start tag expected, '<' not found
Error: 1: Start tag expected, '<' not found

Traceback:

1. XML::xmlParse(filePath, encoding = "UTF-16")
2. (function (msg, ...) 
 . {
 .     if (length(grep("\\\n$", msg)) == 0) 
 .         paste(msg, "\n", sep = "")
 .     if (immediate) 
 .         cat(msg)
 .     if (length(msg) == 0) {
 .         e = simpleError(paste(1:length(messages), messages, sep = ": ", 
 .             collapse = ""))
 .         class(e) = c(class, class(e))
 .         stop(e)
 .     }
 .     messages <<- c(messages, msg)
 . })(character(0))

检查文件是否实际上是“UTF-16”编码的最后一次尝试(在 R 中)产生:

> f <- file(filePath, 'r', encoding = "UTF-16")
> firstLine <- readLines(f, n=1)
> close(f)
> print(line)

[1] "<?xml version=\"1.0\" encoding=\"utf-16\"?>"

这对我来说看起来很合适。


问题)

有谁知道这里发生了什么?这是来自 XML 库的错误吗?该文件是否可能不是“UTF-16”编码的,即使它声称它是???当我将文件打印到 shell 中时,我看到的两个问号是什么?正确读取文件时不会出现这些问号...

标签: rxmlparsingencodingutf-16

解决方案


这是来自 XML 库的错误吗?

我认为这里可能存在错误。如果我生成一个有效的 UTF-16 XML 文档,它将有一个初始字节顺序标记

$ echo '<a></a>' | iconv -t utf-16 >a-utf16.xml
$ xxd a-utf16.xml 
00000000: fffe 3c00 6100 3e00 3dd8 0ade 3c00 2f00  ..<.a.>.=...<./.
00000010: 6100 3e00 0a00                           a.>...

然后我可以解析它:

> XML::xmlParse('a-utf16.xml')
<?xml version="1.0"?>
<a>&#x1F60A;</a>

如果我指定编码:

> XML::xmlParse('a-utf16.xml', encoding='utf-16')
Start tag expected, '<' not found
Error: 1: Start tag expected, '<' not found

您最初的问题是当您没有指定编码时。然而:

我知道这个文件没有损坏,因为下面的 Python 代码似乎可以工作

这是一个很好的提示,但我认为您会发现不适用的极端情况。尝试iconv就文件是否正确编码寻求第二意见。

对于更具体的响应,您需要发布可重现的 XML 文件,


推荐阅读