我有以下XML:
<rss version="2.0">
<channel>
...
<item>
<link>http://stackoverflow.com</link>
<atom:link xmlns:atom="http://www.w3.org/2005/Atom" href="http://stackoverflow.com"/>
...
</item>
</channel>
</rss>
我想提取link
属性,我有以下结构:
type Item struct {
Link string `xml:"http://www.w3.org/2005/Atom link"`
}
我知道,我需要一个前缀来获取链接,但因为没有给出命名空间(以xmls
- 属性的形式,但我不知道,如何。
当然,我可以将所有:*link
- 属性保存到切片中,但我确信有更好的解决方案。
提前致谢!
答案 0 :(得分:1)
标准库encoding/xml
包中的命名空间处理似乎是一个很大的临时性,并且具有相同名称的不同命名空间中的元素似乎是一个触发器。
理想情况下,您可以将给定的XML解码为以下结构:
type Rss struct {
Items []Item `xml:"channel>item"`
}
type Item struct {
Link string `xml:"link"`
AtomLink AtomLink `xml:"http://www.w3.org/2005/Atom link"`
}
type AtomLink struct {
Href string `xml:"href,attr"`
}
但这会导致错误main.Item field "Link" with tag "link" conflicts with field "AtomLink" with tag "http://www.w3.org/2005/Atom link"
(如http://play.golang.org/p/LgW-vm4euL所示)。
但是,如果我们通过注释掉<atom:link>
字段来决定忽略Item.AtomLink
元素,那么我们最终会解码一个空字符串,因为xml:"link"
匹配<link>
任何命名空间中的元素,而不仅仅是空命名空间。最终的<atom:link>
元素为空,因此不会返回任何内容。
一些可能的解决方法包括:
仅尝试解码<atom:link>
元素,因为它可以唯一选择。如果您还处理没有Atom命名空间元素的RSS源,这可能没用。
通过修改要使用的<link>
结构来收集所有Item
元素的内容:
Links []string `xml:"link"`
然后丢弃切片中的任何空字符串。
在一天结束时,程序包需要某种方式来引用空白名称空间。这可能需要新的语法,以保持现有程序正常运行。