xml:编码“utf-16”声明但 Decoder.CharsetReader 为零解组成功

Posted

技术标签:

【中文标题】xml:编码“utf-16”声明但 Decoder.CharsetReader 为零解组成功【英文标题】:xml: encoding "utf-16" declared but Decoder.CharsetReader is nil unmarshal successful 【发布时间】:2018-06-12 08:04:05 【问题描述】:

我正在尝试将包含德语字符(例如 ß、ä、Ö、ü 等)的 XML 提要解组到一个结构中,这会导致错误:xml: encoding "utf-16" declared but Decoder.CharsetReader is nil unmarshal successful

基本上这就是我正在做的事情(省略了对有效部分的错误检查):

resp, _ := http.Get(url)
defer resp.Body.Close()
bodyBytes, _ := ioutil.ReadAll(resp.Body)
err = xml.Unmarshal(bodyBytes, &target)
if err != nil 
  fmt.Println(err)

我尝试使用 github.com/basgys/goxml2json 将 xml 转换为 json,我尝试在解组之前转换为字符串并返回 []byte,我尝试使用其他 SO 答案中发布的各种解码器(因为它假设 charset reader 为 nil),如:

reader := bytes.NewReader(bodyBytes)
decoder := xml.NewDecoder(reader)
decoder.CharsetReader = charset.NewReader
err = decoder.Decode(&target)
if err != nil 
  fmt.Println(err)

无论我尝试了什么,它都无法将 xml 提要解组/解码到结构中。在某些情况下,它最终会将所有文本转换为中文而不是德语。

【问题讨论】:

你能否提供一个你试图解组的xml数据的例子,以及目标值的类型定义。 请提供问题的独立示例。 @mkopriva 我还在测试,但看起来你在解决问题之前发布的答案..也许可以重新发布,这样我就可以接受了:) @jack 我已将其删除,因为我还没有实际测试过它,并且我认为它可能会因某种形式的 utf16 字符串而失败,在这种情况下,您需要实现一个将 utf16 转换为utf8.我将取消删除答案并为可能偶然发现答案的任何其他读者添加注释。 【参考方案1】:

如果您在第二个示例中使用的charset.NewReader 来自https://godoc.org/golang.org/x/net/html/charset,那么代码甚至不应该编译,因为CharsetReader 字段的签名与NewReader 不同。


要修复错误,您可以提供一个“相同”的字符集阅读器,即返回输入不变的阅读器。

func identReader(encoding string, input io.Reader) (io.Reader, error) 
    return input, nil


// ...

decoder.CharsetReader = identReader

https://play.golang.org/p/BiU4T2qz1Z1


注意:上述解决方案适用于问题中的示例字符,但对于其他 utf16 字符串可能会失败。在这种情况下,应该提供可以将 utf16 转换为 utf8 的自定义字符集阅读器,而不是 identReader

【讨论】:

这对我尝试使用 encoding="ISO-8859-7" 解析 xml 很有用。干杯!

以上是关于xml:编码“utf-16”声明但 Decoder.CharsetReader 为零解组成功的主要内容,如果未能解决你的问题,请参考以下文章

Web API 无法使用 utf-16 编码的 XML 绑定 POST 模型

转换编码 --GBK---UTF16---UTF8

为啥 .net 对字符串使用 UTF16 编码,但默认使用 UTF-8 来保存文件?

Stax 解析器无法读取编码为 UTF-16 的文件

编码问题

将XML转换为Json(标记为UTF-16但具有UTF-8内容的文档)