I have a struct with nested array of struct in format below, I have promoted News struct which is in struct array URL
My RSS Feed is : https://foreignpolicy.com/feed/
Here is the tool I used to generate Go struct from my RSS feed 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"`
}
Here is the Goplayround promote News struct
I want to go one step further to promote everything in Channel , so that I can access items in News struct directly from top most Rss struct:
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"`
}
So I can print it as below :
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")
}
But it seems print nothing Goplayground Promote Channel
CodePudding user response:
You can do
URL []struct { News } `xml:"channel>item"`
and remove the channel>item
from the Loc
's tag.
The embedding of the News
type in []struct{ }
seems superfluous. So you can instead do
URL []News `xml:"channel>item"`
and you'll get the same result.
And I'd recommend that you use names that match the XML's element names, i.e. Item
instead of News
and Items
instead of URL
.
Items []Item `xml:"channel>item"`
https://go.dev/play/p/1Ig7wtxckqJ
The xml.Unmarshal
documentation on >
in struct tags says the following:
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 ">".