XML.com: XML From the Inside Out
oreilly.comSafari Bookshelf.Conferences.

advertisement

ROME in a Day: Parse and Publish Feeds in Java
by Mark Woodman | Pages: 1, 2, 3, 4, 5, 6


The addFooter() Method

This method is handed a SyndEntry instance, which represents an RSS item or Atom entry. Our main task in this method is to determine the best place to add our HTML footer. Many feeds have escaped HTML in their <description /> elements, and many others put HTML in a CDATA block in a <content:encoded /> element. The latter is certainly preferable, so we should look for those first and fall back to escaped HTML in <description /> only as a last resort.

If the above makes you cringe, you aren't alone. The dirty secret of syndicated feeds is that XML best practices often have been flushed right down the toilet. But that isn't our problem to solve in this program, so let's move on.

As mentioned earlier, we're going to use ROME's ContentModule to discover whether there are <content:encoded /> elements we can use. This namespace isn't actually part of any RSS or Atom specification, but was rather added later to address the misery of escaped HTML. ROME uses modules to implement the specifics of such add-ons.

As we dig into this method, we'll need to grab the value of the SyndEntry's title and link. These values will be used in createFooter() to build the HTML provided by our FeedWarmer.

/**
 * Add FeedWarmer footer to an entry.
 * @param entry
 */
private void addFooter(SyndEntry entry)
{
    // Prep variables used in loops
    String title = entry.getTitle();
    String link = entry.getLink();

    // Use the add-on ContentModule to handle
    // <content:encoded/> elments within the feed
    ContentModule module =
            ((ContentModule) entry.getModule(CONTENT_NS));

We've asked for the ContentModule by referencing the namespace stored as a constant on the class itself. If the module isn't null, that means the entry does in fact have one or more <content:encoded /> elements. We can use that module to grab the encoded strings from the SyndEntry, add a footer to each, and set the "warmed" encoded strings back on the SyndEntry:

    // If content:encoded is found, use that.
    if(module!=null)
    {
        // Container for footer-appended HTML strings
        List newStringList = new ArrayList();

        // Iterate through encoded HTML, creating footers
        Iterator oldStringIter =
                module.getEncodeds().iterator();
        while (oldStringIter.hasNext())
        {
            String original = (String) oldStringIter.next();
            newStringList.add(createFooter(original,
                              link, title));
        }

        // Set new encoded HTML strings on entry
        module.setEncodeds(newStringList);
    }

If we don't have a module, it means that only a description or its semantic equivalent is available on the bean. Since there may be more than one, we'll iterate through each and add our HTML footer. ROME will take care of escaping the HTML, if that is necessary, upon output.

    else
    {
        // Fall back to adding footer in description
        // This results in escaped HTML.  Ugly, but common.
        Iterator contentIter = entry.getContents().iterator();
        while (contentIter.hasNext())
        {
            // Target the description node
            SyndContent content =
                    (SyndContent) contentIter.next();

            // Create and set a footer-appended description
            String original = content.getValue();
            content.setValue(createFooter(original,
                             link, title));
        }
    }
}

That wraps up addFooter(). We now need to code up the createFooter() method, which is the last real work left.

Pages: 1, 2, 3, 4, 5, 6

Next Pagearrow