我有一个Web服务,我希望收到两个不同的请求;一个被称为Request
,只包含一个Request
,另一个被称为RequestBulk
,其中包含一系列Request
s。两者都映射到Golang结构如下:
type RequestBulk struct {
XMLName xml.Name `xml:"https://item.com RequestBulk"`
Message string `xml:"Message"`
Request []Request `xml:"Request,omitempty"`
}
type Request struct {
XMLName xml.Name `xml:"https://item.com Request"`
Text string `xml:"text"`
}
解组以下XML按预期工作:
<Request xmlns="https://item.com">
<text>Some request text</text>
</Request>
<RequestBulk xmlns="https://item.com">
<Message>Some Text</Message>
<Request xmlns="https://item.com">
<text>Some request text</text>
</Request>
<Request xmlns="https://item.com">
<text>Some other request text</text>
</Request>
</RequestBulk>
在RequestBulk
,如果我改变
Request []Request `xml:"Request,omitempty"`
至
RequestMessage []Request `xml:"RequestMessage,omitempty"`
并将XML更改为:
<RequestBulk xmlns="https://item.com">
<Message>Some Text</Message>
<RequestMessage xmlns="https://item.com">
<text>Some request text</text>
</RequestMessage>
<RequestMessage xmlns="https://item.com">
<text>Some other request text</text>
</RequestMessage>
</RequestBulk>
我收到以下错误:
期望的元素类型<Request>但具有<RequestMessage>
显然是因为XMLName xml.Name `xml:"https://item.com Request"`
如何保持Request
结构不变,仍然接受RequestBulk
类型的消息,结构Request
的名称不同,即RequestMessage
?
换一种说法;如何在不同的命名空间中使用相同的结构?
在Go Playground上运行它。
您可以实现Unmarshaler
接口来覆盖元素的本地名称,然后将元素传递给解码器以进行实际的解组。
func (r *Request) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
if start.Name.Local == "RequestMessage" {
start.Name.Local = "Request" // overwrite
}
type tmp Request // avoid infinite recursive calls to Request.UnmarshalXML
return d.DecodeElement((*tmp)(r), &start) // unmarshal
}