mark nottingham

XPointer: Friend or Foe?

Saturday, 7 February 2004

XML

One of the uglier corners in the Web architecture is the relationship between fragment ids (the bit of the URI at the end, after the “#”) and content negotiation. In a nutshell, because dereferencing a single URI can return multiple formats, and because the fragID is interpreted by the client based on the format, it’s possible to have a fragID mean wildly different things across representations of a single resource.

For example, consider this URI:

http://www.example.org/news#fire

If both XHTML and RSS representations are available through content negotiation, the fragID “fire” has to result in a meaningful view in both formats. This turns out to be pretty simple; in HTML, you wrap the title of that story with <a name=”fire”> … </a>, and in RSS, you’d declare an extension attribute on the <rss:item/> that has a type of ID (probably in a DTD).

That example works because the fragment identifier is something that the author has explicitly given as a key in the document, and there’s a reasonable expectation that it’ll work across all representations of the resource.

Now, consider a URI using XPointer, the W3C-sanctioned alternate fragment identifier syntax for XML:

http://www.example.com/news#xpointer(//stories/fire)

What’s going on here? Instead of just using an explicit key from the publisher, XPointer enables you to index into a document’s structure. As a result, you don’t need the author to do anything; you’re able to index into any part of a document without coordination with the author.

This has been touted as one of XPointer’s big advantages, but it also leads to brittleness; there’s no guarantee that representations of the resource won’t vary in format. This is especially a concern when some of the representations may not even be in an XML format, or when they are, and the XPointer leads one to a false result.

What to do?

These problems aren’t limited to XML and XPointer; there’s also been discussion of a similar fragID syntax for plain text formats. The heart of the matter is that without some form of guarantee — either implicit or explicit — that representations won’t vary, you can’t be confident that fragment identifiers will be valid.

It’s also not just about content negotiation; the structure of the format is just one way that representations can vary. Much of the same effects are seen if the representation varies over time, for example.

The TAG has already stated that authors should try to assure that fragment identifiers are consistent;

A resource owner who creates a URI with a fragment identifier and who uses content negotiation to serve multiple representations of the identified resource SHOULD NOT serve representations with inconsistent fragment identifier semantics.

That’s great, but it ignores the elephant in the room; using XPointer makes it extraordinarily difficult to honour. I think the TAG needs to go one step further; they should instruct format authors — who are responsible for determining the range of content identifiers’ semantics in the first place — to define format-generic fragment identifiers, like “fire” instead of “xpointer(id(fire))”. For XML, a generic mechanism like xml:id would be a big help here.

Since there will always be a need to index into content without involving its author, there will always be a place for things like XPointer. However, they shouldn’t be the primary means of identifying fragments for any format, and the TAG should require such mechanisms to document their dangers. People who use them should understand that representations of resources can vary — both across time and by format, as well as on other axes — so they shouldn’t make too many assumptions about structure.

These use cases could be helped along by metadata to indicate authors’ guarantees about a resource’s representations; for example, if there were a way to definitively say “this resource’s representations do not vary by format or over time,” it would be possible to use XPointer with much more confidence.


2 Comments

Mark said:

You’re not actually allowed to do that with RSS, because it is explicitly spec’d as a DTD-less format. Except Netscape’s RSS 0.91, which has its own DTD which can not be extended.

Saturday, February 7 2004 at 9:04 AM