With the recent release of RSS 2.0 by Userland, there's been a healthy amount of discussion over the smallest part of the spec: Extending RSS. This document attempts to clarify that section, by discussing the creation of the blogChannel Module from Dave Winer, and the underlying principles of namespaces.
This document is not intended to be the "end-all, be-all" of namespace discussions. For the sake of simplicity, I've left a lot of things out and I'm not talking in all the "right technical terms". If you have a healthy knowledge of namespaces already, you'll probably find something to nitpick about, and that's ok... this document is not definitive but rather an end-level, low-tech bundle of joy.
This is a work-in-progress. Email morbus@disobey.com concerning modifications, thoughts, etc.
Without getting overly complicated, a namespace is like a toy chest. "You can buy as many toys as you want", your Mother says, "but at the end of the day, be sure to put them away". You know your Mother has a reason for saying this, because you've seen your Father fall a few times, thus breaking your new toys. The loss of time, money, and back pain mowing lawns is not a pleasant one.
In RSS (and its parent technology, XML), a namespace ensures that your toys won't be tripping up your father's feet. To bring this out of metaphor land and into reality, namespaces allow you to create any new element you desire, without causing problems with other elements.
Let's show a simple example. In the document below, I've randomly
decided to include a <banking>
element for each of my
<item>
's. In this case, I'm saying "I'd like to add a
new element called <banking>
, which tells the name of
the bank I'm using" (yeah, it's a piss-poor example, but it'll make
sense in a second):
<item> <title>A simple example</title> <description>A simple example</description> <banking>Bank of Montreal</banking> </item>
Now, this is all fine and dandy until you think about the world around you. Take a look at this example, created by some smarmy guy in Washington who wanted to add his own elements, just like you:
<item> <title>A simple example</title> <description>A simple example</description> <banking>Turn the rudder 45 degrees to the left.</banking> </item>
It's obvious that his definition of <banking>
(how
a plane moves through the air) is different than your definition of
<banking>
(what bank you place transactions at). This
is an example of "breaking your father's back" - since you didn't put
your toys in your toy chest, problems are occurring. How are your readers
supposed to know which <banking>
is being talked
about? Airplanes or financials? That's where namespaces come in.
Here's an example of another <item>
only with
namespaces added:
<item> <title>A simple example</title> <description>A simple example</description> <airplanes:banking>Turn the rudder 45 degrees to the left.</airplanes:banking> <financial:banking>Bank of Montreal</financial:banking> </item>
Do you see what we've done here? We've preceded each
<banking>
element with another name and a colon (:).
When you create a namespace, you choose an arbitrary prefix (like
"airplanes" or "financial"), throw on a colon (ending up with
"airplanes:" and "financial:" and add your element name ("banking",
which creates the examples shown above).
The benefit for a piece of software is immediate: it now knows that
one sort of banking is different than another sort of banking. There was
no way it could tell this without namespaces. Note that I've used
meaningful names above, but you don't have to - you could easily have
used <blah:banking>
and <flintstones:banking>
.
To software, the difference would still be relevant, but it merely
makes things more confusing for human readers of your RSS feed.
Just choosing a namespace prefix isn't all, though. You also have
to choose a namespace URL [nitpick], one that you have control over, and which
will never change. We'll see where this comes in later, but for now,
I'm going to say that the URL for the "financial" namespace is
http://www.example.com/financial#
and the URL for the
"airplanes" namespace is http://www.foobar.com/ns/airplanes/
.
Generically speaking, you want to end your URL with either
#
or /
[nitpick]. The
reasons why are multifold, but just trust us on this one. These URLs
don't have to resolve to any document (but it's good practice to have a
document explaining more about the elements).
The first module available for RSS 2.0 was
blogChannel
created by Dave Winer. It's a rather simple addition that brings three
new elements to your RSS 2.0 feed, blogRoll, mySubscriptions, and blink.
These new elements are child elements of the normal <channel>
element that has existed within RSS since day one. You can see
them in use here and as a quick sample below:
<rss version="2.0" xmlns="http://backend.userland.com/rss2" xmlns:blogChannel="http://backend.userland.com/blogChannelModule"> <channel> <title>Scripting News</title> <link>http://www.scripting.com/</link> <blogChannel:blogRoll>http://radio.weblogs.com/ ... /file.opml</blogChannel:blogRoll> <blogChannel:mySubscriptions>http://ra ... /file.opml</blogChannel:mySubscriptions> <blogChannel:blink>http://inessential.com/</blogChannel:blink> . . . </channel> </rss>
Let's note a couple of things:
http://backend.userland.com/blogChannelModule
as his
namespace URL. Thankfully, he's also placed a document explaining more about
the module at this address. This allows curious humans to find out more without
going on a witch hunt.xmlns:[namespace prefix]="[namespace url]"
to
the <rss>
element, we're signaling to RSS software
(like an aggregator) that we're planning on using that namespace in
our RSS feed. This is called a namespace declaration.blogChannel
as his namespace prefix, so the three
new elements in his RSS feed are prefixed with blogChannel:
,
like <blogChannel:blogRoll>
, <blogChannel:blink>
, etc.With the above in mind, let's add our fictional <banking>
elements:
<rss version="2.0" xmlns="http://backend.userland.com/rss2" xmlns:blogChannel="http://backend.userland.com/blogChannelModule" xmlns:financial="http://www.example.com/financial#" xmlns:airplanes="http://www.foobar.com/ns/airplanes/"> <channel> <title>Scripting News</title> <link>http://www.scripting.com/</link> <blogChannel:blogRoll>http://radio.weblogs.com/ ... /file.opml</blogChannel:blogRoll> <blogChannel:mySubscriptions>http://ra ... /file.opml</blogChannel:mySubscriptions> <blogChannel:blink>http://inessential.com/</blogChannel:blink> . . . <item> <title>A simple example</title> <description>A simple example</description> <airplanes:banking>Turn the rudder 45 degrees to the left.</airplanes:banking> <financial:banking>Bank of Montreal</financial:banking> </item> . . . </channel> </rss>
Here, we've added our namespace declarations to
<rss>
, continued on with the same
<blogChannel>
examples as before, but also added an
<item>
which includes our two <banking>
elements. These elements both contain the different namespace
prefixes we declared in <rss>
. And that, as they
say, is that. For aggregators and software that understand our new
elements, they'll be golden - for those that don't, our new elements
will be silently ignored.
<wqe412>
when
<color>
is a lot more understandable.woot
is crap when shirt
makes more sense
(combining this with the above maxim, you've got <shirt:color>
instead of <woot:wqe412>
)./
or #
. People will thank you, and you'll
be supporting a good practice that would take a long time to
explain, but equals lots of candy. You'll probably run into namespace
URLs that don't end in either of these characters, and that's
okay too.blogChannel
above for his namespace
prefix doesn't mean that, in my own RSS document, I can't use a prefix
more to my liking (perhaps winer
).<channel>
or <item>
. The
below is a BAD namespace as it is a parent (one that contains other
RSS 2.0 elements):
<ecommerce:product> <item> <title>Sisters</title> <description>A wonderful movie from Brian De Palma</description> </item> </ecommerce:product>The above changes the structure of the RSS feed, and will cause problems with software that expects an
<item>
to
be a child of <channel>
, not
<ecommerce:product>
. All of the previous
examples have been children only, since they contain no other
elements. On the other hand, you can do the following, since
the new namespace doesn't interfere with the structure of
other RSS 2.0 elements:
<item> <title>Sisters</title> <description>A wonderful movie from Brian De Palma</description> </item> <ecommerce:product> <movie:title>Sisters</movie:title> <movie:description>Brian De Palma</movie:description> </ecommerce:product>
Have other do's or do not's? Email morbus@disobey.com.
#
and /
to end a namespace URL is
from RDF (RSS 1.0 being an RDF document). RDF concatenates elements
onto their namespace URL, creating one unique URI. In XML,
concatenation doesn't occur - the namespace URL and element are
treated as a two item list. Ending your namespace URLs with
#
or /
will make your RSS 2.0 extensions
easier to reuse in RDF.Have other complaints? Email morbus@disobey.com.
Thanks to Ken MacLeod, Sean Palmer, Phil Ringnalda, and Aaron Swartz for early and crucial comments concerning this document. You all forced me to include the Nitpicks section because you're crazy ninjas. Visual Credits: 1. Some innocent family's baptism photos, 2. A 1979 tin bank of Pebbles and Bamm Bamm - it was manufactured as part of a set that all bear the words "Bedrock Bank Unbreakable" on the sides, 3. What happens when you type "woot" into Google's image search, 4. Self-explanatory.
#
or /
and that's a-ok (thanks Jon Hanna).