英文:
Unmarshalling to instantiated empty interface in golang
问题
我正在尝试将其反序列化为一个空的go接口类型的变量。具体类型具有正确的xml标签,但由于某种原因,我无法反序列化xml值。它们只是变为空值。
以下是我想要实现的代码:
type Address struct {
    City, State string
}
type Result struct {
    XMLName xml.Name `xml:"Person"`
    Name    string   `xml:"FullName" json:"FullName"`
    Address interface{}
}
func main() {
    xmlAddress := &Address{}
    xmlResult := &Result{Name: "none", Address: xmlAddress}
    xmlData := `
        <Person>
            <FullName>Mike McCartney</FullName>
            <Address>
                <City>Austin</City>
                <State>Texas</State>
            </Address>
        </Person>
    `
    err := xml.Unmarshal([]byte(xmlData), xmlResult)
    // xmlResult = {"XMLName":{"Space":"","Local":"Person"},"FullName":"Mike McCartney","Address":{"City":"Austin","State":"Texas"}}
}
完整代码:https://play.golang.org/p/QXyoOPMFZr
但在我自己的带有实际xml和命名空间的示例中,它不起作用:
type Envelope struct {
    XMLName xml.Name `xml:"http://www.w3.org/2003/05/soap-envelope Envelope"`
    Body    Body     `xml:"http://www.w3.org/2003/05/soap-envelope Body"`
}
type Body struct {
    XMLName xml.Name `xml:"http://www.w3.org/2003/05/soap-envelope Body"`
    Content interface{}
}
type DebtorGetNameResponse struct {
    XMLName             xml.Name `xml:"http://e-conomic.com Debtor_GetNameResponse"`
    DebtorGetNameResult string   `xml:"Debtor_GetNameResult"`
}
func main() {
    xmlData := `
    <?xml version="1.0" encoding="utf-8"?>
    <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
        <soap:Body>
            <Debtor_GetNameResponse xmlns="http://e-conomic.com">
                <Debtor_GetNameResult>THIS SHOULD BE IN THE OUTPUT</Debtor_GetNameResult>
            </Debtor_GetNameResponse>
        </soap:Body>
    </soap:Envelope>`
    e := new(Envelope)
    res := new(DebtorGetNameResponse)
    e.Body = Body{Content: res}
    err := xml.Unmarshal([]byte(xmlData), e)
    // res = {"XMLName":{"Space":"","Local":""},"DebtorGetNameResult":""}
}
完整代码:https://play.golang.org/p/AsV1LGW1lR
英文:
I am trying to unmarshall into a variable of the empty go interface type. The concrete type has proper xml tags, but for some reason i cannot unmarshall the xml values. They just turn up empty.
This code does what I want to do:
type Address struct {
	City, State string
}
type Result struct {
	XMLName xml.Name `xml:"Person"`
	Name    string   `xml:"FullName" json:"FullName"`
	Address interface{}
}
func main() {
	xmlAddress := &Address{}
	xmlResult := &Result{Name: "none", Address: xmlAddress}
	xmlData := `
    <Person>
        <FullName>Mike McCartney</FullName>
        <Address>
            <City>Austin</City>
            <State>Texas</State>
        </Address>
    </Person>
`
	err := xml.Unmarshal([]byte(xmlData), xmlResult)
	// xmlResult = {"XMLName":{"Space":"","Local":"Person"},"FullName":"Mike McCartney","Address":{"City":"Austin","State":"Texas"}}
}
Full code: https://play.golang.org/p/QXyoOPMFZr
But in my own example with actual xml with namespaces it doesn't work:
type Envelope struct {
	XMLName xml.Name `xml:"http://www.w3.org/2003/05/soap-envelope Envelope"`
	Body    Body     `xml:"http://www.w3.org/2003/05/soap-envelope Body"`
}
type Body struct {
	XMLName xml.Name `xml:"http://www.w3.org/2003/05/soap-envelope Body"`
	Content interface{}
}
type DebtorGetNameResponse struct {
	XMLName             xml.Name `xml:"http://e-conomic.com Debtor_GetNameResponse"`
	DebtorGetNameResult string   `xml:"Debtor_GetNameResult"`
}
func main() {
	xmlData := `
	<?xml version="1.0" encoding="utf-8"?>
	<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
		<soap:Body>
			<Debtor_GetNameResponse xmlns="http://e-conomic.com">
				<Debtor_GetNameResult>THIS SHOULD BE IN THE OUTPUT</Debtor_GetNameResult>
			</Debtor_GetNameResponse>
		</soap:Body>
	</soap:Envelope>`
	e := new(Envelope)
	res := new(DebtorGetNameResponse)
	e.Body = Body{Content: res}
	err := xml.Unmarshal([]byte(xmlData), e)
	// res = {"XMLName":{"Space":"","Local":""},"DebtorGetNameResult":""}
}
Full code: https://play.golang.org/p/AsV1LGW1lR
答案1
得分: 1
你需要将xml标签添加到你的interface{}中,例如:
Content interface{} `xml:"http://e-conomic.com Debtor_GetNameResponse"`
在你的另一个示例中,Address interface{}可以工作,因为它的名称与xml标签<Address></Address>相同,并且Unmarshal通过名称进行查找。
英文:
You need to add the xml tags to your interface{}, ie.
Content interface{} `xml:"http://e-conomic.com Debtor_GetNameResponse"`
Address interface{} in your other example works because its name is the same of the xml tag <Address></Address> and Unmarshal lookups by it.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论