func (ap *Parser) parseSource(p *xpp.XMLPullParser) (*Source, error) { if err := p.Expect(xpp.StartTag, "source"); err != nil { return nil, err } source := &Source{} contributors := []*Person{} authors := []*Person{} categories := []*Category{} links := []*Link{} extensions := ext.Extensions{} for { tok, err := p.NextTag() if err != nil { return nil, err } if tok == xpp.EndTag { break } if tok == xpp.StartTag { name := strings.ToLower(p.Name) if shared.IsExtension(p) { e, err := shared.ParseExtension(extensions, p) if err != nil { return nil, err } extensions = e } else if name == "title" { result, err := ap.parseAtomText(p) if err != nil { return nil, err } source.Title = result } else if name == "id" { result, err := ap.parseAtomText(p) if err != nil { return nil, err } source.ID = result } else if name == "updated" || name == "modified" { result, err := ap.parseAtomText(p) if err != nil { return nil, err } source.Updated = result date, err := shared.ParseDate(result) if err == nil { utcDate := date.UTC() source.UpdatedParsed = &utcDate } } else if name == "subtitle" || name == "tagline" { result, err := ap.parseAtomText(p) if err != nil { return nil, err } source.Subtitle = result } else if name == "link" { result, err := ap.parseLink(p) if err != nil { return nil, err } links = append(links, result) } else if name == "generator" { result, err := ap.parseGenerator(p) if err != nil { return nil, err } source.Generator = result } else if name == "icon" { result, err := ap.parseAtomText(p) if err != nil { return nil, err } source.Icon = result } else if name == "logo" { result, err := ap.parseAtomText(p) if err != nil { return nil, err } source.Logo = result } else if name == "rights" || name == "copyright" { result, err := ap.parseAtomText(p) if err != nil { return nil, err } source.Rights = result } else if name == "contributor" { result, err := ap.parsePerson("contributor", p) if err != nil { return nil, err } contributors = append(contributors, result) } else if name == "author" { result, err := ap.parsePerson("author", p) if err != nil { return nil, err } authors = append(authors, result) } else if name == "category" { result, err := ap.parseCategory(p) if err != nil { return nil, err } categories = append(categories, result) } else { err := p.Skip() if err != nil { return nil, err } } } } if len(categories) > 0 { source.Categories = categories } if len(authors) > 0 { source.Authors = authors } if len(contributors) > 0 { source.Contributors = contributors } if len(links) > 0 { source.Links = links } if len(extensions) > 0 { source.Extensions = extensions } if err := p.Expect(xpp.EndTag, "source"); err != nil { return nil, err } return source, nil }
func (ap *Parser) parseEntry(p *xpp.XMLPullParser) (*Entry, error) { if err := p.Expect(xpp.StartTag, "entry"); err != nil { return nil, err } entry := &Entry{} contributors := []*Person{} authors := []*Person{} categories := []*Category{} links := []*Link{} extensions := ext.Extensions{} for { tok, err := p.NextTag() if err != nil { return nil, err } if tok == xpp.EndTag { break } if tok == xpp.StartTag { name := strings.ToLower(p.Name) if shared.IsExtension(p) { e, err := shared.ParseExtension(extensions, p) if err != nil { return nil, err } extensions = e } else if name == "title" { result, err := ap.parseAtomText(p) if err != nil { return nil, err } entry.Title = result } else if name == "id" { result, err := ap.parseAtomText(p) if err != nil { return nil, err } entry.ID = result } else if name == "rights" || name == "copyright" { result, err := ap.parseAtomText(p) if err != nil { return nil, err } entry.Rights = result } else if name == "summary" { result, err := ap.parseAtomText(p) if err != nil { return nil, err } entry.Summary = result } else if name == "source" { result, err := ap.parseSource(p) if err != nil { return nil, err } entry.Source = result } else if name == "updated" || name == "modified" { result, err := ap.parseAtomText(p) if err != nil { return nil, err } entry.Updated = result date, err := shared.ParseDate(result) if err == nil { utcDate := date.UTC() entry.UpdatedParsed = &utcDate } } else if name == "contributor" { result, err := ap.parsePerson("contributor", p) if err != nil { return nil, err } contributors = append(contributors, result) } else if name == "author" { result, err := ap.parsePerson("author", p) if err != nil { return nil, err } authors = append(authors, result) } else if name == "category" { result, err := ap.parseCategory(p) if err != nil { return nil, err } categories = append(categories, result) } else if name == "link" { result, err := ap.parseLink(p) if err != nil { return nil, err } links = append(links, result) } else if name == "published" || name == "issued" { result, err := ap.parseAtomText(p) if err != nil { return nil, err } entry.Published = result date, err := shared.ParseDate(result) if err == nil { utcDate := date.UTC() entry.PublishedParsed = &utcDate } } else if name == "content" { result, err := ap.parseContent(p) if err != nil { return nil, err } entry.Content = result } else { err := p.Skip() if err != nil { return nil, err } } } } if len(categories) > 0 { entry.Categories = categories } if len(authors) > 0 { entry.Authors = authors } if len(links) > 0 { entry.Links = links } if len(contributors) > 0 { entry.Contributors = contributors } if len(extensions) > 0 { entry.Extensions = extensions } if err := p.Expect(xpp.EndTag, "entry"); err != nil { return nil, err } return entry, nil }
func (rp *Parser) parseRoot(p *xpp.XMLPullParser) (*Feed, error) { rssErr := p.Expect(xpp.StartTag, "rss") rdfErr := p.Expect(xpp.StartTag, "rdf") if rssErr != nil && rdfErr != nil { return nil, fmt.Errorf("%s or %s", rssErr.Error(), rdfErr.Error()) } // Items found in feed root var channel *Feed var textinput *TextInput var image *Image items := []*Item{} ver := rp.parseVersion(p) for { tok, err := p.NextTag() if err != nil { return nil, err } if tok == xpp.EndTag { break } if tok == xpp.StartTag { // Skip any extensions found in the feed root. if shared.IsExtension(p) { p.Skip() continue } name := strings.ToLower(p.Name) if name == "channel" { channel, err = rp.parseChannel(p) if err != nil { fmt.Printf("error in channel: %s\n", err) return nil, err } } else if name == "item" { item, err := rp.parseItem(p) if err != nil { return nil, err } items = append(items, item) } else if name == "textinput" { textinput, err = rp.parseTextInput(p) if err != nil { return nil, err } } else if name == "image" { image, err = rp.parseImage(p) if err != nil { return nil, err } } else { p.Skip() } } } rssErr = p.Expect(xpp.EndTag, "rss") rdfErr = p.Expect(xpp.EndTag, "rdf") if rssErr != nil && rdfErr != nil { return nil, fmt.Errorf("%s or %s", rssErr.Error(), rdfErr.Error()) } if channel == nil { channel = &Feed{} channel.Items = []*Item{} } if len(items) > 0 { channel.Items = append(channel.Items, items...) } if textinput != nil { channel.TextInput = textinput } if image != nil { channel.Image = image } channel.Version = ver return channel, nil }
func (rp *Parser) parseItem(p *xpp.XMLPullParser) (item *Item, err error) { if err = p.Expect(xpp.StartTag, "item"); err != nil { return nil, err } item = &Item{} extensions := ext.Extensions{} categories := []*Category{} for { tok, err := p.NextTag() if err != nil { return nil, err } if tok == xpp.EndTag { break } if tok == xpp.StartTag { name := strings.ToLower(p.Name) if shared.IsExtension(p) { ext, err := shared.ParseExtension(extensions, p) if err != nil { return nil, err } item.Extensions = ext } else if name == "title" { result, err := shared.ParseText(p) if err != nil { return nil, err } item.Title = result } else if name == "description" { result, err := shared.ParseText(p) if err != nil { return nil, err } item.Description = result } else if name == "link" { result, err := shared.ParseText(p) if err != nil { return nil, err } item.Link = result } else if name == "author" { result, err := shared.ParseText(p) if err != nil { return nil, err } item.Author = result } else if name == "comments" { result, err := shared.ParseText(p) if err != nil { return nil, err } item.Comments = result } else if name == "pubdate" { result, err := shared.ParseText(p) if err != nil { return nil, err } item.PubDate = result date, err := shared.ParseDate(result) if err == nil { utcDate := date.UTC() item.PubDateParsed = &utcDate } } else if name == "source" { result, err := rp.parseSource(p) if err != nil { return nil, err } item.Source = result } else if name == "enclosure" { result, err := rp.parseEnclosure(p) if err != nil { return nil, err } item.Enclosure = result } else if name == "guid" { result, err := rp.parseGUID(p) if err != nil { return nil, err } item.GUID = result } else if name == "category" { result, err := rp.parseCategory(p) if err != nil { return nil, err } categories = append(categories, result) } else { // Skip any elements not part of the item spec p.Skip() } } } if len(categories) > 0 { item.Categories = categories } if len(extensions) > 0 { item.Extensions = extensions if itunes, ok := item.Extensions["itunes"]; ok { item.ITunesExt = ext.NewITunesItemExtension(itunes) } if dc, ok := item.Extensions["dc"]; ok { item.DublinCoreExt = ext.NewDublinCoreExtension(dc) } } if err = p.Expect(xpp.EndTag, "item"); err != nil { return nil, err } return item, nil }
func (rp *Parser) parseChannel(p *xpp.XMLPullParser) (rss *Feed, err error) { if err = p.Expect(xpp.StartTag, "channel"); err != nil { return nil, err } rss = &Feed{} rss.Items = []*Item{} extensions := ext.Extensions{} categories := []*Category{} for { tok, err := p.NextTag() if err != nil { return nil, err } if tok == xpp.EndTag { break } if tok == xpp.StartTag { name := strings.ToLower(p.Name) if shared.IsExtension(p) { ext, err := shared.ParseExtension(extensions, p) if err != nil { return nil, err } extensions = ext } else if name == "title" { result, err := shared.ParseText(p) if err != nil { return nil, err } rss.Title = result } else if name == "description" { result, err := shared.ParseText(p) if err != nil { return nil, err } rss.Description = result } else if name == "link" { result, err := shared.ParseText(p) if err != nil { return nil, err } rss.Link = result } else if name == "language" { result, err := shared.ParseText(p) if err != nil { return nil, err } rss.Language = result } else if name == "copyright" { result, err := shared.ParseText(p) if err != nil { return nil, err } rss.Copyright = result } else if name == "managingeditor" { result, err := shared.ParseText(p) if err != nil { return nil, err } rss.ManagingEditor = result } else if name == "webmaster" { result, err := shared.ParseText(p) if err != nil { return nil, err } rss.WebMaster = result } else if name == "pubdate" { result, err := shared.ParseText(p) if err != nil { return nil, err } rss.PubDate = result date, err := shared.ParseDate(result) if err == nil { utcDate := date.UTC() rss.PubDateParsed = &utcDate } } else if name == "lastbuilddate" { result, err := shared.ParseText(p) if err != nil { return nil, err } rss.LastBuildDate = result date, err := shared.ParseDate(result) if err == nil { utcDate := date.UTC() rss.LastBuildDateParsed = &utcDate } } else if name == "generator" { result, err := shared.ParseText(p) if err != nil { return nil, err } rss.Generator = result } else if name == "docs" { result, err := shared.ParseText(p) if err != nil { return nil, err } rss.Docs = result } else if name == "ttl" { result, err := shared.ParseText(p) if err != nil { return nil, err } rss.TTL = result } else if name == "rating" { result, err := shared.ParseText(p) if err != nil { return nil, err } rss.Rating = result } else if name == "skiphours" { result, err := rp.parseSkipHours(p) if err != nil { return nil, err } rss.SkipHours = result } else if name == "skipdays" { result, err := rp.parseSkipDays(p) if err != nil { return nil, err } rss.SkipDays = result } else if name == "item" { result, err := rp.parseItem(p) if err != nil { return nil, err } rss.Items = append(rss.Items, result) } else if name == "cloud" { result, err := rp.parseCloud(p) if err != nil { return nil, err } rss.Cloud = result } else if name == "category" { result, err := rp.parseCategory(p) if err != nil { return nil, err } categories = append(categories, result) } else if name == "image" { result, err := rp.parseImage(p) if err != nil { return nil, err } rss.Image = result } else if name == "textinput" { result, err := rp.parseTextInput(p) if err != nil { return nil, err } rss.TextInput = result } else { // Skip element as it isn't an extension and not // part of the spec p.Skip() } } } if err = p.Expect(xpp.EndTag, "channel"); err != nil { return nil, err } if len(categories) > 0 { rss.Categories = categories } if len(extensions) > 0 { rss.Extensions = extensions if itunes, ok := rss.Extensions["itunes"]; ok { rss.ITunesExt = ext.NewITunesFeedExtension(itunes) } if dc, ok := rss.Extensions["dc"]; ok { rss.DublinCoreExt = ext.NewDublinCoreExtension(dc) } } return rss, nil }