XML 对于 Golang 中的数组,解组属性不同
XML Unmarshalling attribute differently in case of arrays in Golang
我有一个 Web 服务,我希望在其中接收到两个不同的请求;一个称为 Request
,仅包含一个 Request
,另一个称为 RequestBulk
,其中包含一个 Request
数组。两者都映射到 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"`
}
解组以下 XMLs 按预期工作:
<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>
我收到以下错误:
expected element type <Request> but have <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
}
我有一个 Web 服务,我希望在其中接收到两个不同的请求;一个称为 Request
,仅包含一个 Request
,另一个称为 RequestBulk
,其中包含一个 Request
数组。两者都映射到 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"`
}
解组以下 XMLs 按预期工作:
<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>
我收到以下错误:
expected element type <Request> but have <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
}