golang 解析rss并返回json?

<rss>
    <channel>
    <title>RSS</title>
    <item>
        <title>23333</title>
        <my:size>7.8 MiB</my:size>
    </item>
    </channel>
</rss>
type RSS struct {
    Channel Channel `xml:"channel"`
}

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

type Item struct {
    Title string `xml:"title"`
    Size  string `xml:"my:size"`
}

func rss(w http.ResponseWriter, r *http.Request) {
    var rss RSS
    err = xml.Unmarshal([]byte(rss_str), &rss)
    if err != nil {
        fmt.Printf("解析 XML 失败: %s\n", err)
        return
    }
    jsonData, err := json.MarshalIndent(rss, "", "  ")
    if err != nil {
        fmt.Printf("转换为 JSON 失败: %s\n", err)
        return
    }

    w.Write(jsonData)
}

就这个 my:size 很难办,我无法正确解析,得到的内容为空

目前我是用

rss_str := strings.ReplaceAll(rss_str, "my:", "")

凑活的,能满足我要求,但总感觉不是个事儿。

请问,该怎么解析带命名空间的xml?
谢谢

阅读 5k
avatarAI BotBETA
要解析带有命名空间的 XML,你需要在结构体字段的标签中指定该命名空间。在 Go 的 `encoding/xml` 包中,你可以通过在 XML 标签中使用 `xmlns` 属性来指定命名空间。

以下是如何修改你的结构体以正确解析带有命名空间的 `my:size` 字段:

type RSS struct {

Channel Channel `xml:"channel"`

}

type Channel struct {

XMLName xml.Name `xml:"channel"`
Title   string   `xml:"title"`
Items   []Item   `xml:"item"`

}

type Item struct {

Title string `xml:"title"`
Size  string `xml:"my:size" xmlns:my="http://example.com/my"`  // 假设命名空间 URI 为 http://example.com/my

}

func rss(w http.ResponseWriter, r *http.Request) {

// 假设 rss_str 是你的 RSS XML 字符串
var rss RSS
err := xml.Unmarshal([]byte(rss_str), &rss)
if err != nil {
    fmt.Printf("解析 XML 失败: %s\n", err)
    return
}
jsonData, err := json.MarshalIndent(rss, "", "  ")
if err != nil {
    fmt.Printf("转换为 JSON 失败: %s\n", err)
    return
}

w.Header().Set("Content-Type", "application/json")
w.Write(jsonData)

}


请注意,你需要将 `xmlns:my` 的值替换为实际的命名空间 URI。这个 URI 应该在你的 RSS XML 文档的顶部或相关部分定义。如果你没有该命名空间的 URI,你可能需要联系 RSS 数据的提供者以获取正确的 URI。

此外,确保在 HTTP 响应中设置正确的 `Content-Type` 头,以便客户端知道返回的是 JSON 数据。
1 个回答

go代码

package main

import (
    "encoding/json"
    "encoding/xml"
    "fmt"
    "strings"
)

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

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

type Item struct {
    Title string `xml:"title"`
    Size  string `xml:"size"`
}

func main() {
    rssStr := `<rss>
    <channel>
        <title>RSS</title>
        <item>
            <title>23333</title>
            <my:size xmlns:my="http://example.com/my">7.8 MiB</my:size>
        </item>
    </channel>
</rss>`

    var rss RSS
    decoder := xml.NewDecoder(strings.NewReader(rssStr))
    var currentElement string

    for {
        token, err := decoder.Token()
        if err != nil {
            break
        }
        switch element := token.(type) {
        case xml.StartElement:
            currentElement = element.Name.Local
            if element.Name.Space == "http://example.com/my" && currentElement == "size" {
                var size string
                decoder.DecodeElement(&size, &element)
                rss.Channel.Items = append(rss.Channel.Items, Item{Size: size})
            }
        case xml.EndElement:
            currentElement = ""
        case xml.CharData:
            if currentElement == "title" {
                rss.Channel.Items = append(rss.Channel.Items, Item{Title: string(element)})
            }
        }
    }

    jsonData, err := json.MarshalIndent(rss, "", "  ")
    if err != nil {
        fmt.Printf("转换为 JSON 失败: %s\n", err)
        return
    }

    fmt.Println(string(jsonData))
}

输出JSON

{
  "Channel": {
    "Title": "",
    "Items": [
      {
        "Title": "23333",
        "Size": "7.8 MiB"
      }
    ]
  }
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏