通过多级提升结构的嵌套数组以进行 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
而不是 News
和 Items
而不是 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
">".
我有一个带有结构嵌套数组的结构,格式如下,我提升了结构数组 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
而不是 News
和 Items
而不是 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 ">".