Valid RSS 2.0 Using Rome
Asked Answered
T

3

7

Im using rome 1.0 to generate RSS for my java application.

In my java:

    SyndFeed feed = new SyndFeedImpl();
    feed.setFeedType( "rss_2.0" );
    feed.setTitle( "My Site" );
    feed.setLink( "http://example.com" );
    feed.setDescription( "Test Site." );    

    List<SyndEntry> entries = new ArrayList<SyndEntry>();
    SyndEntry entry = null;
    SyndContent description = null;

    entry = new SyndEntryImpl();
    entry.setTitle( "Entry1" );
    entry.setLink( "http://example.com/entry1" );
    entry.setPublishedDate( new Date() );

    description = new SyndContentImpl();
    description.setType("text/html");
    description.setValue( "This is the content of entry 1." );
    entry.setDescription( description );

    entries.add( entry );
    feed.setEntries(entries);

    Writer writer = new FileWriter("/home/jr/Desktop/stream.xml");
    SyndFeedOutput output = new SyndFeedOutput();
    output.output(feed,writer);
    writer.close();

The generated RSS:

<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>My Site</title>
    <link>http://example.com</link>
    <description>Test Site.</description>
    <item>
      <title>Entry1</title>
      <link>http://example.com/entry1</link>
      <description>This is the content of entry 1.</description>
      <pubDate>Fri, 09 Nov 2012 01:28:57 GMT</pubDate>
      <guid>http://example.com/entry1</guid>
      <dc:date>2012-11-09T01:28:57Z</dc:date>
    </item>
  </channel>
</rss>

When RSS is validated here, it has the following recommendations:

  • An item should not include both pubDate and dc:date
  • Missing atom:link with rel="self"

How to do the recommendation in rome library? Is the generated RSS ok?

Thanks.

Tamathatamaulipas answered 9/11, 2012 at 1:38 Comment(2)
Partially answered in atom:link in RSS using Rome.Erlanger
Just wanted to mention that @JoshC13's answer indeed works, but it should be applied to SyndEntryImpl instead of SyndFeedImpl, since the duplicated date is happening under the <item> elementMetopic
C
2

In your custom SyndFeed class, make sure that you name your Date variable differently from what's on the SyndFeed class (Ie: instead of 'publishedDate', use something like 'pubDate'. This seems to have solved the issue for me.

public class CustomSyndFeed extends SyndFeedImpl {

protected Date pubDate;

    @Override
    public Date getPublishedDate() {
        return pubDate;
    }

    @Override
    public void setPublishedDate(final Date pubDate) {
        this.pubDate = new Date(pubDate.getTime());
    }
}
Chrisom answered 3/6, 2015 at 17:28 Comment(1)
Hello Happy Coder! I see you're new here, so just a heads-up. We usually try to reserve answers for new techniques or approaches and use comments for small addendums like changing variable names since they don't represent an alternative approach. I understand your plight since the reputation requirements put the comments section off-limits for now. Perhaps stating your problem here: meta.stackexchange.com/questions/12119/… would be useful.Any
A
1

So this is happening because the SyndFeedImpl uses the same field for the date and publishedDate fields (from the DC Module) :

@Override
public Date getPublishedDate() {
    return getDCModule().getDate();
}

@Override
public void setPublishedDate(final Date publishedDate) {
    getDCModule().setDate(publishedDate);
}

Since the RSS093Generator (used by the RSS20Generator) creates a pubDate element from the specified item, but also inherits from the DCModuleGenerator, you get both this:

final Date pubDate = item.getPubDate();
        if (pubDate != null) {
            eItem.addContent(generateSimpleElement("pubDate", DateParser.formatRFC822(pubDate, Locale.US)));
        }

and this:

final Date dcDate = dcModule.getDate();
if (dcDate != null) {
    for (final Date date : dcModule.getDates()) {
        element.addContent(generateSimpleElement("date", DateParser.formatW3CDateTime(date, Locale.US)));
    }
}

This interaction can be prevented by implementing a custom SyndFeed of your own. In this case, all you need to do is create a class variable to store your pubDate so that the DCModule never gets a date set, and will therefore never generate your unwanted dc:date element.

I ran into the exact same problem and solved it by using this SyndFeed implementation:

public class CustomSyndFeed extends SyndFeedImpl {

    protected Date publishedDate;

    @Override
    public Date getPublishedDate() {
        return publishedDate;
    }

    @Override
    public void setPublishedDate(final Date publishedDate) {
        this.publishedDate = new Date(publishedDate.getTime());
    }
}
Any answered 30/12, 2014 at 3:44 Comment(0)
E
1

Little late to the party, but no answer here works out of the box, so I figured I'd add mine.

As @Vitor points out in his comment, the correct way of doing this to extend SyndEntryImpl and use it as SyndEntry entry = new CustomEntryImpl();.

public class CustomEntryImpl extends SyndEntryImpl {

    protected Date pubDate;

    @Override
    public Date getPublishedDate() {
        return pubDate;
    }

    @Override
    public void setPublishedDate(final Date pubDate) {
        this.pubDate = new Date(pubDate.getTime());
    }
}
Entrammel answered 9/2, 2017 at 18:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.