« Werner sums it up | Main | Data above the level of a single site »

LML: List Markup Language


Introduction

LML is a markup language for lists*. There are many lists on the Web and in web content, but most of them are published using HTML elements which don't carry much interesting information about the list. LML can enable sharing of these lists along with useful metadata. LML documents can contain lists of most anything. They can be ordered lists, such as a top ten lists of books, the world's twenty most populous countries, or unordered such as a wishlist, a playlist, or a shopping basket.

The markup is straightforward. Here's an example skeleton:

   <i:lml xmlns:i='http://www.dehora.net/lml/2005/01'
       i:version='001' >
     <i:published i:when='' />
     <i:changed i:when='' />
     <i:author>
        <i:name></i:name>
     </i:author>
     <i:category>
        <i:name></i:name>
        <i:subject></i:subject>
     </i:category>
     <i:list i:ordered='' i:href=''>
       <i:item i:href=''></i:item>
       <i:item i:href=''></i:item>
       <i:item i:href=''></i:item>
     </i:list>
   </i:lml>

Let's go through it.

General notes

  1. None of the elements are optional.
  2. None of the child elements of the root element are ordered.
  3. Attributes are in namespace.
  4. You're free to insert foreign markup into an LML document.
  5. You're free to ignore foreign markup in an LML document.

i:lml

The i:lml element in the http://www.dehora.net/lml/2005/01 namespace,

   <i:lml xmlns:i='http://www.dehora.net/lml/2005/01'
       i:version='001' >

says this is an LML document. The i:version attribute contains a textual identifier - it's not optional. The version we're talking about here is '001'.

i:category, i:name, i:subject

     <i:category>
        <i:name></i:name>
        <i:subject></i:subject>
     </i:category>

This lets you associate the list with category metadata. You can have as many i:category elements as you want. The i:name element is the name of the category. The i:subject indicates a URL that qualifies or contextualizes the category - it can be empty. Preserving the XML document order for these items is sufficient.

i:published

The i:published element,

     <i:published i:when='' />

indicates the date the list was published - it's an empty element. The i:when attribute contains the date conforming to the date-time BNF rule in RFC3339.

i:changed

The i:changed element,

     <i:changed i:when='' />

indicates a date the LML document was changed - it's an empty element. The i:when attribute contains the date conforming to the date-time BNF rule in RFC3339. The first time a list is published i:changed and i:published will be the same date.

i:author, i:name

The i:author construct,

     <i:author>
        <i:name></i:name>
     </i:author>

is lifted from Atom's.

i:list

     <i:list i:ordered='' i:href=''>

The i:list element tells us the list of items has started. The i:ordered attribute can have the values 'yes' or 'no' - it's not optional. The i:href attribute indicates a link where the list can be found or read on the Web - it's not optional. The semantics of ordering is undefined - specifying it would be a) interminably dull, b) of minimal benefit.

i:item

An i:list contains one or more i:item elements:

     <i:list i:ordered='yes' i:href=''>
       <i:item i:href=''></i:item>
       <i:item i:href=''></i:item>
       <i:item i:href=''></i:item>
     </i:list>

the i:href attribute indicates the resource name of the item - it's optional.

What you put in the content of an i:item is up to you. If you put some LML in an item, i:category elements in your outer LML document do not apply to the embedded LML.

Media type

The intended media type for LML is application/xml+lml. Who knows how long it will take to get that registered, but try winging it for now and see how things work out. If you don't like using unregistered media types, application/xml is fine.

Future work

It would interesting to

  • define an RDF serialization of LML and accompanying XSLT sheets which specify the mappings.
  • hack support for LML into RSS aggregators and blog publishing tools.
  • scrape exisiting web sites for their lists and republish as LML.

A RelaxNG schema and an LML to XHTML transform should be forthcoming in a future edition.


* Credit is due to Clyde Hatter for coming up with the idea of a markup for lists.


January 8, 2005 03:20 AM

Comments

Keith Gaughan
(January 10, 2005 06:12 PM #)

[Keith left an odd comment which I kept, but elided (he's welcome to help me make sense of it). I think his point was that OPML can already do lists. Spec: http://www.opml.org/spec]

Keith Gaughan
(January 12, 2005 09:32 PM #)

I was doing a gentle pastiche of Dave's possible reaction to LML.

As it happens, I think OPML and LML are probably equivalent anyway, albeit OPML has a lot of extra nonsense in its element (like ), though thankfully the lot of it is optional.

Lion Kimbro
(January 13, 2005 09:41 AM #)

You need a way to link to elements within other lists in other people's list feeds.

nLSD has this functionality, implemented. It doesn't just have lists, it also has dictionaries, and, (unimplemented, but planned): Functions, and function results.

But, really: You can make this list thing 100x more useful, in the one step of making it possible to link into other lists.

Keith Gaughan
(January 13, 2005 03:18 PM #)

@Lion: Why not just use XLinks?

Bill de hra
(January 14, 2005 11:32 PM #)


"Why not just use XLinks?"

Currently being discussed on xml-dev as dead tech. It seems requiring two attributes instead of one killed it - such is the way of complexity. Then again, Xlink gets partially reinvented from time to time - witness Atom's @link construct, which is a wee bit messy.


"You need a way to link to elements within other lists in other people's list feeds."

Lion has a fair point. I haven't though about this at all.

I wonder if you wouldn't be better off upgrading OPML; some people complain about it being underspecified, but I really like the way you can nest it.