packagemainimport("io/ioutil""encoding/xml""html/template""log")typeRss2struct{XMLNamexml.Name`xml:"rss"`Versionstring`xml:"version,attr"`// RequiredTitlestring`xml:"channel>title"`Linkstring`xml:"channel>link"`Descriptionstring`xml:"channel>description"`// OptionalPubDatestring`xml:"channel>pubDate"`ItemList[]Item`xml:"channel>item"`}typeItemstruct{// RequiredTitlestring`xml:"title"`Linkstring`xml:"link"`Descriptiontemplate.HTML`xml:"description"`// OptionalContenttemplate.HTML`xml:"encoded"`PubDatestring`xml:"pubDate"`Commentsstring`xml:"comments"`}typeAtom1struct{XMLNamexml.Name`xml:"http://www.w3.org/2005/Atom feed"`Titlestring`xml:"title"`Subtitlestring`xml:"subtitle"`Idstring`xml:"id"`Updatedstring`xml:"updated"`Rightsstring`xml:"rights"`LinkLink`xml:"link"`AuthorAuthor`xml:"author"`EntryList[]Entry`xml:"entry"`}typeLinkstruct{Hrefstring`xml:"href,attr"`}typeAuthorstruct{Namestring`xml:"name"`Emailstring`xml:"email"`}typeEntrystruct{Titlestring`xml:"title"`Summarystring`xml:"summary"`Contentstring`xml:"content"`Idstring`xml:"id"`Updatedstring`xml:"updated"`LinkLink`xml:"link"`AuthorAuthor`xml:"author"`}funcatom1ToRss2(aAtom1)Rss2{r:=Rss2{Title:a.Title,Link:a.Link.Href,Description:a.Subtitle,PubDate:a.Updated,}r.ItemList=make([]Item,len(a.EntryList))fori,entry:=rangea.EntryList{r.ItemList[i].Title=entry.Titler.ItemList[i].Link=entry.Link.Hrefifentry.Content==""{r.ItemList[i].Description=template.HTML(entry.Summary)}else{r.ItemList[i].Description=template.HTML(entry.Content)}}returnr}constatomErrStr="expected element type <rss> but have <feed>"funcparseAtom(content[]byte)(Rss2,bool){a:=Atom1{}err:=xml.Unmarshal(content,&a)iferr!=nil{log.Println(err)returnRss2{},false}returnatom1ToRss2(a),true}funcparseFeedContent(content[]byte)(Rss2,bool){v:=Rss2{}err:=xml.Unmarshal(content,&v)iferr!=nil{iferr.Error()==atomErrStr{// try Atom 1.0returnparseAtom(content)}log.Println(err)returnv,false}ifv.Version=="2.0"{// RSS 2.0fori,_:=rangev.ItemList{ifv.ItemList[i].Content!=""{v.ItemList[i].Description=v.ItemList[i].Content}}returnv,true}log.Println("not RSS 2.0")returnv,false}funcmain(){// parse sample rss feedxmlContent1,_:=ioutil.ReadFile("example-6.xml")r1,ok1:=parseFeedContent(xmlContent1)ifok1{log.Println(r1.Title)}else{log.Println("fail to read example-6")}// parse sample atom feedxmlContent2,_:=ioutil.ReadFile("example-7.xml")r2,ok2:=parseFeedContent(xmlContent2)ifok2{log.Println(r2.Title)}else{log.Println("fail to read example-7")}// parse opmlxmlContent3,_:=ioutil.ReadFile("example-5.xml")r3,ok3:=parseFeedContent(xmlContent3)ifok3{log.Println(r3.Title)}else{log.Println("fail to read example-5")}}
Main logic of the parseFeedContent function:
Given xml content, the function tries to parse the content in RSS format.
If success, return the parsed result.
If parsing RSS fails, then try to parse the content in Atom 1.0 format. If
success, convert the Atom format to RSS format and return the parsed result.