why do I get “_xmlns” when marshalling an RSS struct?

polaris · 2016-08-19 07:00:11 · 779 次点击    
这是一个分享于 2016-08-19 07:00:11 的资源,其中的信息可能已经有所发展或是发生改变。

After reading a RSS feed, I want to marshall it again (e. g. after filtering some items), but I get an weird xmlns:_xmlns="xmlns", _xmlns:content="...", _xmlns:atom="...". The code ...

package main

import (
    "encoding/json"
    "encoding/xml"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "os"
)

type Rss2 struct {
    XMLName      xml.Name `xml:"rss"`
    Version      string   `xml:"version,attr"`
    XmlnsContent string   `xml:"xmlns content,attr"`
    XmlnsAtom    string   `xml:"xmlns atom,attr"`
    Title        string   `xml:"channel>title"`
}

func main() {
    var err error

    response, err := http.Get(os.Args[1])

    if err != nil {
        log.Fatal(err)
    }

    defer response.Body.Close()

    body, err := ioutil.ReadAll(response.Body)

    if err != nil {
        log.Fatal(err)
    }

    rss := Rss2{}
    err = xml.Unmarshal(body, &rss)

    // all fine ...
    json, err := json.Marshal(rss)
    fmt.Println();
    fmt.Println(string(json))

    // strange _xmlns ...
    marshalled, err := xml.Marshal(rss)
    fmt.Println();
    fmt.Println(string(marshalled))

}

gives me this output:

$ go run rss-xmlns.go http://www.zdnet.com/news/rss.xml

{"XMLName":{"Space":"","Local":"rss"},"Version":"2.0","XmlnsContent":"","XmlnsAtom":"http://www.w3.org/2005/Atom","Title":"Latest news"}

<rss version="2.0" xmlns:_xmlns="xmlns" _xmlns:content="" _xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Latest news</title></channel></rss>

... any idea why? What did I miss?


评论:

JHunz:

Pretty sure your tags are just wrong.

type Rss2 struct {
    XMLName      xml.Name `xml:"rss"`
    Version      string   `xml:"version,attr"`
    XmlnsContent string   `xml:"xmlns:content,attr"`
    XmlnsAtom    string   `xml:"xmlns:atom,attr"`
    Title        string   `xml:"channel>title"`
}
memorylane:

That is brilliant! Thank you! You don't know how much pain xmlns reproduction has caused me. I never thought about using : in the tags because they differ in marshaling and un-marshaling.

coke4all:

unfortunately this does not solve the problem: with xml:"xmlns:content,attr" and xml:"xmlns:atom,attr" now I get this output:

$ go run rss-xmlns.go http://www.zdnet.com/news/rss.xml
{"XMLName":{"Space":"","Local":"rss"},"Version":"2.0","XmlnsContent":"","XmlnsAtom":"","Title":"Latest news"}
<rss version="2.0" xmlns:content="" xmlns:atom=""><channel><title>Latest news</title></channel></rss>

... the marshalling (second line, the XML output) seems to be okay, but the unmarshalling of the RSS feed (first line, the JSON output) prints an empty XmlnsAtom. I don't have to create two structures, one with space for unmarshalling, one with : for marshalling?! Do I have to?!?

memorylane:

Yes, as far as I can tell, you need two structures if you want to reproduce the xmlns declarations when marshalling. If you don't care about recreating those then you can use one structure.

memorylane:

The _ is prepended by this code which checks if your prefix starts with xml.


入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

779 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传