英文:
Promote nested array of struct by multi level for XML decoding
问题
我有一个嵌套结构的结构体,格式如下,我提升了在结构体数组中的News结构体,它在结构体数组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"`
}
我想进一步提升Channel中的所有内容,这样我就可以直接从最顶层的Rss结构体中访问News结构体中的项:
type Rss struct {
XMLName xml.Name `xml:"rss"`
Channel --> 似乎不起作用?
}
type Channel struct {
URL []struct {
News
}
}
type News struct {
Loc string `xml:"channel>item>link"` --> 这是正确的XML标签吗?
Publishdate string `xml:"pubDate"` --> 还是这是正确的XML标签?
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解析器 *************************/
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提升Channel的示例
英文:
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
答案1
得分: 2
你可以这样做:
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
关于结构标签中的>
,xml.Unmarshal
文档中有以下说明:
> 如果XML元素包含一个子元素,其名称与标记格式为“a”或“a>b>c”的前缀匹配,unmarshal将进入XML结构,寻找具有给定名称的元素,并将最内层的元素映射到该结构字段。以“>”开头的标记等效于以字段名称开头,后跟“>”。
https://pkg.go.dev/encoding/xml@go1.18.2#Unmarshal
英文:
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
> ">".
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论