Golang中XML无法映射到结构体问题排查及原因分析
解决Go中XML到结构体映射时切片为空的问题
你的代码出现panic是因为XML解析后DataRequestList切片是空的,根本原因是结构体字段缺少正确的XML标签,导致解析器无法将XML中的<FileDetails>元素映射到这个切片上。
问题分析
在你的XML结构里,<Data>节点下包含多个<FileDetails>子节点,但你的DataRequest结构体中的DataRequestList字段没有指定对应的XML标签——XML解析器完全不知道这个字段应该对应哪些XML元素,自然不会填充任何数据,切片保持为空,最后访问DataRequestList[0]时就触发了索引越界的panic。
修正后的代码
只需要给DataRequestList字段添加xml:"FileDetails"标签,明确告诉解析器:<Data>下的所有<FileDetails>元素都要映射到这个切片中:
package main import ( "encoding/xml" "fmt" ) func main() { type FileDetails struct { XMLName xml.Name `xml:"FileDetails"` FileName string FileSize string } type DataRequest struct { XMLName xml.Name `xml:"Data"` // 关键:添加xml标签关联FileDetails元素 DataRequestList []FileDetails `xml:"FileDetails"` } type Request struct { XMLName xml.Name `xml:"Request"` DataReqObject DataRequest `xml:"Data"` } req := Request{} data := ` <Request> <Data> <FileDetails> <FileName>abc</FileName> <FileSize>10</FileSize> </FileDetails> <FileDetails> <FileName>pqr</FileName> <FileSize>20</FileSize> </FileDetails> </Data> </Request> ` err := xml.Unmarshal([]byte(data), &req) if err != nil { fmt.Printf("error: %v", err) return } fmt.Printf("XMLName: %#v\n", req.XMLName) fmt.Printf("Data: %v\n", req.DataReqObject) fmt.Printf("First FileDetails: %v\n", req.DataReqObject.DataRequestList[0]) }
运行结果
修正后执行代码,会得到符合预期的输出:
XMLName: xml.Name{Space:"", Local:"Request"} Data: {{ Data} [{FileDetails abc 10} {FileDetails pqr 20}]} First FileDetails: {FileDetails abc 10}
总结
当你需要将XML中同一父节点下的多个同类型子元素映射到结构体的切片字段时,必须给切片字段指定对应XML元素名称的标签——这是Go的encoding/xml包解析规则的要求,没有标签的话,解析器无法建立字段和XML元素的关联关系。
内容的提问来源于stack exchange,提问作者user5155835
相关产品推荐
相关产品推荐

