Firefox/Sage bookmarks to Google Reader import

Want to migrate your RSS bookmarks from Firefox (or its RSS-reading addon, Sage) to Google Reader? I did, just now.

Christopher Hinze has written a great Firefox addon that exports bookmarks to OPML 1.0. Unfortunately, OPML is a bit of an anything-goes specification. So although Hinze's plugin produces valid OPML, it isn't the same sort of valid OPML that Google Reader expects. Google Reader, in fact, gags and chokes on Hinze's OPML, and refuses to import it.

The main problem is that the <outline/> element, the basic hierarchical building block for OPML, will take any attributes. What does that mean in practice? Well, here's what Hinze's export produces:

<outline text="Coding">
  <outline type="link" text="Joel on Software" url="http://www.joelonsoftware.com/rss.xml" />
</outline>

and here's the result of Google Reader exporting its own store of RSS bookmarks:

<outline title="Coding" text="Coding">
  <outline text="drupal.org - Community plumbing"
    title="drupal.org - Community plumbing" type="rss"
    xmlUrl="http://drupal.org/node/feed" htmlUrl="http://drupal.org"/>
</outline>

To a computer, these are fundamentally two different data formats: the URLs are stored in different attributes, and there are attributes on each that either have different values or are not present on the other. Someone did a DTD for OPML: looking at those two apparently analogous fragments above you have to ask yourself why they bothered.

Help is at hand, though. This sort of problem is bread and butter to XSLT, and here's an XSL transform for converting Firefox OPML to Google Reader OPML. If you have xsltproc installed on your system, you would type:

xsltproc http://www.jpstacey.info/applications/google/ff2gr_opml.xsl bookmarks.opml > fixed_bookmarks.opml

Or download the XSLT---it's released under GPL2---and run it locally, changing that URL there to a local file location.

One thing to note: the XSLT will remove an outline wrapped around your bookmarks with title "Sage Feeds" (case-sensitive). So you can export that branch of your bookmarks, and the XSLT will strip the wrapper off and you won't import a load of bookmarks tagged "Sage Feeds". If you don't like this behaviour then either rename your Sage bookmark container, or learn XSLT: it won't kill you.