嵌套自定义类型时 xml Unmarshal 中缺少值

Missing value in xml Unmarshal when custom type is nested

提问人:程柏硯 提问时间:9/5/2023 最后编辑:程柏硯 更新时间:9/7/2023 访问量:44

问:

首先,我想解码成一个结构体,所以我有:<gd:name

type GDName struct {
    GivenName string `xml:"gd givenName"`
}

然后解码

    bs := []byte(`  <gd:name>
    <gd:givenName>FIRST_NAME</gd:givenName>
    </gd:name>
    `)

    var n GDName
    err := xml.Unmarshal(bs, &n)
    if err != nil {
        fmt.Println(err)
    }

    fmt.Printf("%#v", n)

但是,当涉及到嵌套字段 xml 字符串时,

<entry>
 <gd:name>
    <gd:givenName>FIRST_NAME</gd:givenName>
 </gd:name>
</entry>

并有

// ContactKind is the contact API used, atom-xml based structure.
// It represents a person's contact data. Such as address, name, email, etc...
// It contains private fields in the real structure.
type ContactKind struct {
    Name GDName
}

type decodeContactKind struct {
    Name GDName `xml:"http://schemas.google.com/g/2005 name"`
}

// UnmarshalXML implements xml.Unmarshaler.
// In the unmarhal processing, common element or server-only element will be read.
func (c *ContactKind) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
    var o decodeContactKind
    err := d.DecodeElement(&o, &start)
    if err != nil {
        return err
    }
    c.Name = GDName{
        GivenName: o.Name.GivenName,
    }

    return nil
}

它无法将 GDName 内容解码到字段中。 这是 snippet and go playground 链接ContactKind.Name

bs2 := []byte(`<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gd='http://schemas.google.com/g/2005'>
<gd:name>
    <gd:givenName>FIRST_NAME</gd:givenName>
</gd:name></entry>`)

    var ct ContactKind
    err = xml.Unmarshal(bs2, &ct)
    if err != nil {
        fmt.Println(err)
    }

    fmt.Printf("%#v", ct.Name)

我预计第二部分会打印与第一部分相同的内容。

main.GDName{GivenName:"FIRST_NAME"}

我想知道为什么它不能工作以及如何修复它以将 GDName 解组到 ContactKind 的 Name 字段中。

xml go xml 解析

评论


答:

0赞 Evgeniy Mikhalev 9/7/2023 #1

这应该可以正常工作(用 xml.Name 字段描述的根条目标记):

type Entry struct {
    XMLName xml.Name `xml:"entry"`
    Name    GDName   `xml:"name"`
}

type GDName struct {
    GivenName string `xml:"givenName"`
}

你可以在这里查看