通过多级提升结构的嵌套数组以进行 XML 解码

Promote nested array of struct by multi level for XML decoding

我有一个带有结构嵌套数组的结构,格式如下,我提升了结构数组 URL

中的新闻结构

我的 RSS 订阅源是https://foreignpolicy.com/feed/

这是我用来从我的 RSS 提要生成 Go 结构的工具 XML to Go struct

type Rss struct {
    XMLName xml.Name `xml:"rss"`
    Channel struct {
        URL []struct {
            News
        } `xml:"item"`
    } `xml:"channel"`
}
type News struct {
    Loc         string `xml:"link"`
    Publishdate string `xml:"pubDate"`
    Title       string `xml:"title"`
    Summary     string `xml:"description"`
}

这是Goplayround promote News struct

我想更进一步推广 Channel 中的所有内容,这样我就可以直接从最顶层 Rss[=37] 访问 News 结构中的项目=]结构:

type Rss struct {
    XMLName xml.Name `xml:"rss"`
    Channel --> seem NOT working ?
}
type Channel struct {
    URL []struct {
        News
    }
}
type News struct {
    Loc         string `xml:"channel>item>link"` ---> is it the right xml tag ?
    Publishdate string `xml:"pubDate"` ---> or this is the right xml tag ?
    Title       string `xml:"title"`
    Summary     string `xml:"description"`
}

所以我可以打印如下:

var URLset Rss
if xmlBytes, err := getXML(url); err != nil {
    fmt.Printf("Failed to get XML: %v", err)
} else {
    xml.Unmarshal(xmlBytes, &URLset)
}
/************************** XML parser *************************/
for _, URLElement := range **URLset.URL** {
    fmt.Println("URLElement:", URLElement)
    fmt.Println(
        "[Element]:",
        "\nTitle #", URLElement.Title,
        "\nPublicationDate #", URLElement.Publishdate,
        "\nSummary#", URLElement.Summary,
        "\nLoc #", URLElement.Loc,
        "\n")
}

但是好像什么也没打印 Goplayground Promote Channel

你可以做到

URL []struct { News } `xml:"channel>item"`

并从 Loc 的标签中删除 channel>item


[]struct{ } 中嵌入 News 类型似乎是多余的。所以你可以改为

URL []News `xml:"channel>item"`

你会得到相同的结果。


我建议您使用与 XML 的元素名称匹配的名称,即 Item 而不是 NewsItems 而不是 URL.

Items []Item `xml:"channel>item"`

https://go.dev/play/p/1Ig7wtxckqJ


关于 > in struct tags 的 xml.Unmarshal 文档说明如下:

If the XML element contains a sub-element whose name matches the prefix of a tag formatted as "a" or "a>b>c", unmarshal will descend into the XML structure looking for elements with the given names, and will map the innermost elements to that struct field. A tag starting with ">" is equivalent to one starting with the field name followed by ">".

https://pkg.go.dev/encoding/xml@go1.18.2#Unmarshal