78 lines
1.3 KiB
Go
78 lines
1.3 KiB
Go
|
package parser
|
||
|
|
||
|
import (
|
||
|
"encoding/xml"
|
||
|
"fmt"
|
||
|
)
|
||
|
|
||
|
type FeedType string
|
||
|
|
||
|
const (
|
||
|
Rss FeedType = "rss"
|
||
|
Atom FeedType = "atom"
|
||
|
)
|
||
|
|
||
|
type FeedEntry struct {
|
||
|
Link string
|
||
|
Content string
|
||
|
}
|
||
|
|
||
|
func ParseFeed(feedType FeedType, data []byte) ([]FeedEntry, error) {
|
||
|
switch feedType {
|
||
|
case Rss:
|
||
|
return parseRss(data)
|
||
|
case Atom:
|
||
|
return parseAtom(data)
|
||
|
}
|
||
|
return nil, fmt.Errorf("Unknown feed type: %s", feedType)
|
||
|
}
|
||
|
|
||
|
func parseAtom(data []byte) ([]FeedEntry, error) {
|
||
|
v := struct {
|
||
|
Items []struct {
|
||
|
Link struct {
|
||
|
Href string `xml:"href,attr"`
|
||
|
} `xml:"link"`
|
||
|
Content string `xml:",innerxml"`
|
||
|
} `xml:"entry"`
|
||
|
}{}
|
||
|
|
||
|
err := xml.Unmarshal(data, &v)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
var feedEntries []FeedEntry
|
||
|
for _, atomEntry := range v.Items {
|
||
|
feedEntries = append(feedEntries, FeedEntry{
|
||
|
Link: atomEntry.Link.Href,
|
||
|
Content: atomEntry.Content,
|
||
|
})
|
||
|
}
|
||
|
return feedEntries, nil
|
||
|
}
|
||
|
func parseRss(data []byte) ([]FeedEntry, error) {
|
||
|
|
||
|
v := struct {
|
||
|
Items []struct {
|
||
|
Link string `xml:"link"`
|
||
|
Content string `xml:",innerxml"`
|
||
|
} `xml:"channel>item"`
|
||
|
}{}
|
||
|
|
||
|
err := xml.Unmarshal(data, &v)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
var feedEntries []FeedEntry
|
||
|
for _, rssEntry := range v.Items {
|
||
|
feedEntries = append(feedEntries, FeedEntry{
|
||
|
Link: rssEntry.Link,
|
||
|
Content: rssEntry.Content,
|
||
|
})
|
||
|
}
|
||
|
|
||
|
return feedEntries, nil
|
||
|
}
|