I’ve been working on OPML, RSS, and other web feeds for a small project I hope to announce soon! OPML was designed by Dave Winer as a format for his outliner software, but is also widely used for web feed subscription lists.

The OPML 2.0 specification defines the following mandatory attributes:

<outline text="Rubenerd"
    type="rss"
    xmlUrl="https://rubenerd.com/feed/" />

It’s also common to see these optional attributes:

<outline text="Rubenerd"
    title="Rubenerd"
    type="rss"
    version="RSS2"
    language="en-SG"
    xmlUrl="https://rubenerd.com/feed/"
    htmlUrl="https://rubenerd.com/" />

Note type and version, which refer to what the target feed is. This works for RSS feeds, which is the bulk of what I use and publish. But what about Atom and JSON Feed? Almost all OPML files I’ve seen reference type="rss" regardless of the target feed’s format. Here’s a reference to an Atom 1.0 feed in a typical OPML file:

<outline text="Martin Fowler" 
    htmlUrl="http://martinfowler.com" 
    type="rss" 
    xmlUrl="http://martinfowler.com/feed.atom" />

But I’ve seen exceptions. Embarcadero Software references Atom feeds in their OPML files with type="ATOM" and version="1.0" for the version:

<outline title="Technical Articles" 
    htmlUrl="https://edn.embarcadero.com/articles/interbase/3rdpartytools" 
    xmlUrl="https://edn.embarcadero.com/articles/interbase/3rdpartytools/feed" 
    type="ATOM" 
    version="1.0" />

I’ve since learned this isn’t technically correct. The specification defines subscription list elements in OPML as having type="rss". Emphasis added:

A subscription list is a possibly multiple-level list of subscriptions to feeds. Each sub-element of the body of the OPML document is a node of type rss or an outline element that contains nodes of type rss.

So how do we disambiguate between disparate feed formats and versions, if type=rss is used to reference feeds in general? The spec grants some leeway in using the version attribute.

The values [that version] can have are: RSS1 for RSS 1.0; RSS for 0.91, 0.92 or 2.0; scriptingNews for scriptingNews format. There are no known values for Atom feeds, but they certainly could be provided.

I was worried about referring to multiple versions with just RSS, but Dave’s subscriptionList example references it numerically like RSS1 above:

type="rss" version="RSS2"

I’ll be referring to Atom feeds with ATOM1 to keep with this convention.

🌲 🌲 🌲

Which leads to the reasonable question, why include this attribute if it’s optional and loosely-defined? Philosophically, I think it’s a shame that RSS, OPML, and related formats have all this expressive syntax that’s almost never used. It hints at an alternative future of the web where decentralised and distributed writers and applications flourished instead of a few social networks.

Pragmatically though, I’m going to use them in my upcoming project. OPML parsers in the real world have to function assuming those above values are missing, or liberally interpret invalid data. I control the data in my tool, so why not use the data if it’s there?