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:
memorylane: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"` }
coke4all: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.
memorylane:unfortunately this does not solve the problem: with
xml:"xmlns:content,attr"
andxml:"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.
The
_
is prepended by this code which checks if your prefix starts with xml.
