Go中的XML解码

Jam*_*ker 5 xml go

我一直在玩Go的XML包,但看不出以下代码有什么问题.

package main

import (
    "encoding/xml"
    "fmt"
    "net/http"
) 

type Channel struct {
    Items Item
}

type Item struct {
    Title       string `xml:"title"`
    Link        string `xml:"link"`
    Description string `xml:"description"`
}

func main() {

    var items = new(Channel)
    res, err := http.Get("http://www.reddit.com/r/google.xml")

    if err != nil {
        fmt.Printf("Error: %v\n", err)
    } else {
        decoded := xml.NewDecoder(res.Body)

        err = decoded.Decode(items)

        if err != nil {
            fmt.Printf("Error: %v\n", err)
        }

        fmt.Printf("Title: %s\n", items.Items.Title)
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码运行没有任何错误,并打印到终端:

Title:
Run Code Online (Sandbox Code Playgroud)

结构似乎是空的,但我不明白为什么它没有填充XML数据.

Nic*_*ood 5

我会像这样完全明确 - 命名所有的XML部分

有关完整工作示例,请参阅游乐场

type Rss struct {
    Channel Channel `xml:"channel"`
}

type Channel struct {
    Title       string `xml:"title"`
    Link        string `xml:"link"`
    Description string `xml:"description"`
    Items       []Item `xml:"item"`
}

type Item struct {
    Title       string `xml:"title"`
    Link        string `xml:"link"`
    Description string `xml:"description"`
}
Run Code Online (Sandbox Code Playgroud)


seh*_*seh 4

您的程序已经很接近了,但需要指定更多的上下文来匹配 XML 文档。

\n\n

您需要修改您的字段标签,以帮助引导 XML 绑定通过您的 \nChannel结构向下到达您的Item结构:

\n\n
type Channel struct {\n    Items []Item `xml:"channel>item"`\n}\n\ntype Item struct {\n    Title       string `xml:"title"`\n    Link        string `xml:"link"`\n    Description string `xml:"description"`\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

根据的文档encoding/xml.Unmarshal(),第七项适用于此处:

\n\n
\n

如果 XML 元素包含名称与格式为“a”或“a>b>c”的标记前缀匹配的子元素,则 unmarshal 将深入到 XML 结构中查找具有给定\n 的元素名称,并将最里面的元素映射到该 struct\n 字段。以 ">" 开头的标记相当于以字段名称开头,后跟 ">" 的标记。

\n
\n\n

在您的情况下,您希望向下遍历顶级<rss>元素的<channel>元素来查找每个<item>元素。但请注意,我们不需要\xe2\x80\x94,实际上可以\'t\xe2\x80\x94通过Channel将字段的标记写为<rss>Items

\n\n
`xml:"rss>channel>item"`\n
Run Code Online (Sandbox Code Playgroud)\n\n

这个上下文是隐含的;提供的结构Unmarshall()已经映射到顶级 XML 元素。

\n\n

还要注意,您的Channel结构体Items字段应该是 slice-of- 类型Item,而不仅仅是单个Item

\n\n
\n\n

您提到您在使该提案发挥作用时遇到了困难。这是我发现的完整列表,正如人们所期望的那样:

\n\n
package main\n\nimport (\n    "encoding/xml"\n    "fmt"\n    "net/http"\n    "os"\n) \n\ntype Channel struct {\n    Items []Item `xml:"channel>item"`\n}\n\ntype Item struct {\n    Title       string `xml:"title"`\n    Link        string `xml:"link"`\n    Description string `xml:"description"`\n}\n\nfunc main() {\n    if res, err := http.Get("http://www.reddit.com/r/google.xml"); err != nil {\n        fmt.Println("Error retrieving resource:", err)\n        os.Exit(1)\n    } else {\n        channel := Channel{}\n        if err := xml.NewDecoder(res.Body).Decode(&channel); err != nil {\n            fmt.Println("Error:", err)\n            os.Exit(1)\n        } else if len(channel.Items) != 0 {\n            item := channel.Items[0]\n            fmt.Println("First title:", item.Title)\n            fmt.Println("First link:", item.Link)\n            fmt.Println("First description:", item.Description)\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n