You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang解析带windows-1251编码声明的XML返回空数组问题

问题根因

Go标准库encoding/xml默认仅支持UTF-8编码的XML内容解析。目标接口返回的内容编码为windows-1251,XML头部声明已明确标注该编码,但直接读取响应字节流调用xml.Unmarshal时,解析器无法自动完成该非UTF-8编码的识别与转码,最终导致解析结果为空。手动删除XML声明只是让解析器默认按UTF-8规则猜测编码,属于碰运气的错误方案,遇到windows-1251编码下的西里尔字母等特殊字符时必然出现乱码,不具备可用性。

修复方案

无需手动修改XML内容、删除头部声明,只需要在读取响应流时增加编码转换步骤,将windows-1251编码的内容转成UTF-8后再做XML解析即可。

  1. 先安装转码依赖:
go get golang.org/x/text/encoding/charmap
go get golang.org/x/text/transform
  1. 调整后的完整可运行代码如下:
package main

import (
	"encoding/xml"
	"fmt"
	"io"
	"net/http"

	"golang.org/x/text/encoding/charmap"
	"golang.org/x/text/transform"
)

type ValCurs struct {
	XMLName xml.Name `xml:"ValCurs"`
	Date    string   `xml:"Date,attr"`
	Name    string   `xml:"name,attr"`
	Valute  []Valute `xml:"Valute"`
}

type Valute struct {
	XMLName  xml.Name `xml:"Valute"`
	CharCode string   `xml:"CharCode"`
	Nominal  string   `xml:"Nominal"`
	Name     string   `xml:"Name"`
	Value    string   `xml:"Value"`
}

func main() {
	resp, err := http.Get("http://www.cbr.ru/scripts/XML_daily.asp")
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	// 包装响应流,读取时自动将windows-1251编码转成UTF-8
	decoder := charmap.Windows1251.NewDecoder()
	utf8Reader := transform.NewReader(resp.Body, decoder)
	req, err := io.ReadAll(utf8Reader)
	if err != nil {
		panic(err)
	}

	var val ValCurs
	err = xml.Unmarshal(req, &val)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%+v\n", val)
}

注意事项

  • 该方案直接在IO读取层完成转码,不会修改原始XML结构,头部的encoding声明保留也不会干扰解析逻辑
  • 原代码结构体标签中逗号后存在多余空格(比如xml:"Date, attr"),该写法会导致xml包无法识别attr标记,无法正确解析节点属性,修复时已一并删除空格
  • 原示例代码忽略了HTTP请求、流读取、XML解析全链路的错误返回,实际使用时必须处理对应错误,否则异常场景下无法定位问题

内容的提问来源于stack exchange,提问作者Remilay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 15:18:15