W3C

RDFa Primer

Embedding Structured Data in Web Pages

W3C Working Draft 17 March 2008

This version:
http://www.w3.org/TR/2008/WD-xhtml-rdfa-primer-20080317/
Latest version:
http://www.w3.org/TR/xhtml-rdfa-primer
Previous version:
http://www.w3.org/TR/2007/WD-xhtml-rdfa-primer-20071026/
Editors:
Ben Adida, Creative Commons <ben@adida.net>
Mark Birbeck, x-port.net Ltd. <mark.birbeck@x-port.net>

Abstract

The modern Web is made up of an enormous number of documents that have been created using HTML. These documents contain significant amounts of structured data, which is largely unavailable to tools and applications. When publishers can express this data more completely, and when tools can read it, a new world of user functionality becomes available, letting users transfer structured data between applications and web sites, and allowing browsing applications to improve the user experience: an event on a web page can be directly imported into a user's desktop calendar; a license on a document can be detected so that users can be informed of their rights automatically; a photo's creator, camera setting information, resolution, location and topic can be published as easily as the original photo itself, enabling structured search and sharing.

RDFa is a specification for attributes to be used with languages such as HTML and XHTML to express structured data. The rendered, hypertext data of XHTML is reused by the RDFa markup, so that publishers don't need to repeat significant data in the document content. This document is an introduction to the use of the RDFa attributes with XHTML. The underlying abstract representation is RDF [RDFPRIMER], which lets publishers build their own vocabulary, extend others, and evolve their vocabulary with maximal interoperability over time. The expressed structure is closely tied to the data, so that rendered data can be copied and pasted along with its relevant structure.

The rules for interpreting the data are generic, so that there is no need for different rules for different formats; this allows authors and publishers of data to define their own formats without having to update software, register formats via a central authority, or worry that two formats may interfere with each other.

RDFa shares some use cases with microformats. Whereas microformats specify both a syntax for embedding structured data into HTML documents and a vocabulary of specific terms for each microformat, RDFa specifies only a syntax and relies on independent specification of terms (often called vocabularies or taxonomies) by others. RDFa allows terms from multiple independently-developed vocabularies to be freely intermixed and is designed such that the language can be parsed without knowledge of the specific term vocabulary being used.

This document is an introduction to RDFa. The normative specification of RDFa may be found in [RDFa-SYNTAX].

Status of this Document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.

This document is joint work of the W3C Semantic Web Deployment Working Group [SWD-WG] and the W3C XHTML2 Working Group [XHTML2-WG]. This work is part of both the W3C Semantic Web Activity and the HTML Activity. The two Working Groups expect to advance the RDFa Syntax to Recommendation Status and then publish a final version of this Primer as a W3C Working Group Note.

This version of the RDFa Primer is a small update to the previous version, bringing it into alignment with the the interpretation of the @src attribute as specified in the 21 February 2008 RDFa Syntax Last Call Working Draft [RDFa-SYNTAX]. These changes are summarized in the Changes section.

Comments on this Working Draft are welcome and may be sent to public-rdf-in-xhtml-tf@w3.org; please include the text "comment" in the subject line. All messages received at this address are viewable in a public archive.

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the XHTML 2 group and another public list of any patent disclosures made in connection with the deliverables of the Semantic Web Deployment Working Group; those pages also include instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

Table of Contents

1 Purpose and Preliminaries
2 Simple Data: Publishing Events and Contacts
    2.1 The Basic XHTML, before RDFa
    2.2 Publishing An Event
    2.3 Publishing Contact Information
    2.4 The Complete XHTML with RDFa
    2.5 Working Within a Fragment of the XHTML
3 Advanced Concepts: Custom Vocabularies, Document Fragments, Complex Data, ...
    3.1 Creating a Custom Vocabulary and Using Compact URIs
    3.2 Qualifying Other Documents and Document Chunks
    3.3 Data Types
    3.4 Layers of Structure — Subresources
    3.5 Using @src on img, and the use of @rev
    3.6 Overriding @href and @src
4 RDF Correspondence
    4.1 Events and Contact Information
    4.2 Custom Vocabularies and Datatypes
    4.3 Layered Data and Subresources
    4.4 Using @src on img, and the use of @rev
    4.5 Overriding @href and @src
5 Case Studies
6 Acknowledgments
7 Bibliography


1 Purpose and Preliminaries

Current Web pages, written in XHTML, contain inherent structured data: calendar events, contact information, photo captions, song titles, copyright licensing information, etc. When authors and publishers can express this data precisely, and when tools can read it robustly, a new world of user functionality becomes available, letting users transfer structured data between applications and Web sites. An event on a Web page can be directly imported into a desktop calendar. A license on a document can be detected to inform the user of his rights automatically. A photo's creator, camera setting information, resolution, and topic can be published as easily as the original photo itself.

RDFa lets XHTML authors express this structured data using existing XHTML attributes and a handful of new ones. Where data, such as a photo caption, is already present on the page for human readers, the author need not repeat it for automated processes to access it. A Web publisher can easily reuse data fields, e.g. an event's date, defined by other publishers, or create new ones altogether. RDFa gets its expressive power from RDF [RDFPRIMER], though the reader need not understand RDF before reading this document.

For simplicity, instead of using RDF terminology, we use the word "field" to indicate a unit of labeled information, e.g. the "first name" field indicates a person's first name.

RDFa uses Compact URIs, which express a URI using a prefix, e.g. dc:title where dc: stands for http://purl.org/dc/elements/1.1/. In this document, for simplicity's sake, the following prefixes are assumed to be already declared: dc for Dublin Core [DC], foaf for Friend-Of-A-Friend [FOAF], cc for Creative Commons [CC], and xsd for XML Schema Definitions [XSD]:

We use standard XHTML notation for elements and attributes: both are denoted using fixed-width lowercase font, e.g. div, and attributes are differentiated using a preceding '@' character, e.g. @href.

For an overview of the use cases for RDFa, the user should consult the [RDFa Use Cases]. For in-depth details on RDFa, including how to implement an RDFa parser, the reader should consult the [RDFa Syntax].

2 Simple Data: Publishing Events and Contacts

Jo keeps a private blog for her friends and family.

2.1 The Basic XHTML, before RDFa

Jo is organizing one last summer Barbecue, which she hopes all of her friends and family will attend. She blogs an announcement of this get-together at her private blog, http://jo-blog.example.org/. Her blog also includes her contact information:

<html>
    <head><title>Jo's Friends and Family Blog</title></head>
    <body>
...
    <p>
        I'm holding one last summer Barbecue, on September 16th at 4pm.
    </p>
...
    <p class="contactinfo">
        Jo Smith. Web hacker
        at
        <a href="http://example.org">
            Example.org
        </a>.
        You can contact me
        <a href="mailto:jo@example.org">
            via email
        </a>.
    </p>
...
    </body>
</html>

This short piece of mark-up contains important structured data.

The markup describes an event: a Barbecue that Jo is hosting. This Barbecue starts at 4pm on September 16th. A summary of the event is "one last summer Barbecue." We also have contact information for Jo: she works for the organization Example.org, with job title of "Web Hacker." She can be contacted at the email address "jo@example.org."

At the moment, it is very difficult for software — like Web browsers and search engines — to make use of this data's implicit structure. We need a standard mechanism to explicitly express it, so that it can be extracted consistently. This is precisely where RDFa comes in.

2.2 Publishing An Event

Jo would like to label this blog entry so that her friends and family can add her Barbecue directly to their calendar. RDFa allows her to express this structure using existing XHTML attributes and a small handful of additional attributes. Since this is a calendar event, Jo will specifically use the iCal vocabulary [ICAL-RDF] to denote the data's structure.

The first step is to reference the iCal vocabulary within the XHTML page, so that Jo's friends' Web browsers can look up the calendar concepts and make use of them:

<html
    xmlns:cal="http://www.w3.org/2002/12/cal/ical#">
    ...

then, Jo declares a new event:

 <p instanceof="cal:Vevent"> ...
    </p>

Note how @instanceof is used here to define the type of data being expressed. The use of this attribute on the p element ensures that, by default, data expressed inside this element refers to the same event. There, Jo can set up the event fields, reusing the existing XHTML. For example, the event summary can be labeled as:

  I'm holding
  <span property="cal:summary">one last summer Barbecue</span>,

@property on span indicate the data field cal:summary. The existing content, "one last summer Barbecue", is the value of this field. Sometimes, this is not the desired effect. Specifically, the start time of the event should be displayed pleasantly — "September 16th" —, but should be represented in a machine-parsable way: 20070916T1600-0500, the standard ISO 8601 format used by iCal (which is cumbersome for human readers). In this case, the markup needs only a slight modification:

  <span property="cal:dtstart" content="20070916T1600-0500">
    September 16th at 4pm
  </span>

The actual content of the span, "September 16th at 4pm", is ignored by RDFA parsers, which instead read from the explicit @content. The full markup is then:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN"
          "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">
<html xmlns:cal="http://www.w3.org/2002/12/cal/ical#">
    <head><title>Jo's Friends and Family Blog</title></head>
    <body>
...
    <p instanceof="cal:Vevent">
        I'm holding
        <span property="cal:summary">one last summer Barbecue</span>,
        on
        <span property="cal:dtstart" content="20070916T1600-0500">
            September 16th at 4pm.
        </span>
    </p>
...
    </body>
</html>

Note that Jo could have used any other XHTML element, not just span, to mark up her event. In other words, when the event information is already laid out in the XHTML using elements such as h1, em, div, etc., Jo can simply add the @instanceof data type declaration, @property, and optionally @content to mark up the event.

(For the RDF-inclined reader, the RDF triples that correspond to the above markup are available in Section 4.1 Events and Contact Information.)

2.3 Publishing Contact Information

Now that Jo has published her event in a human-and-machine-readable way, she realizes there is much data on her blog that she can mark up in the same way. Her contact information, in particular, is an easy target:

...
  <p class="contactinfo">
    Jo Smith. Web hacker
    at
    <a href="http://example.org">
        Example.org
    </a>.
    You can contact me
      <a href="mailto:jo@example.org">
        via email
      </a>.
  </p>
...

Jo discovers the vCard RDF vocabulary [VCARD-RDF], which she adds to her existing page. The vCard format is a standard representation for contact information. Thus, Jo uses the prefix contact to designate this vocabulary. Note that adding the vCard vocabulary is just as easy and does not interfere with the already added iCal vocabulary:

<html xmlns:cal="http://www.w3.org/2002/12/cal/ical#"
      xmlns:contact="http://www.w3.org/2001/vcard-rdf/3.0#">
...

Jo then sets up her vCard using RDFa, by deciding that the p will be the container for her vcard. She notes that the vCard schema does not require declaring a vCard type. Instead, it is recommended that a vCard refer to a Web page that identifies the individual. For this purpose, Jo can use @about, a new attribute introduced by RDFa indicating that all contained XHTML pertains to Jo's designated URI. The @about value is inherited from ancestor elements in the XHTML: in this case, all HTML contained within p will apply to the @about on the p element.

...
  <p class="contactinfo" about="http://example.org/staff/jo">
        
      <!-- everything here pertains to http://example.org/staff/jo -->

  </p>
...

"Simple enough!" Jo realizes, noting that RDFa does not interfere with her existing markup, in particular the @class she uses for styling. She adds her first vCard fields: name, title, organization and email.

...
  <p class="contactinfo"  about="http://example.org/staff/jo">
        
    <span property="contact:fn">Jo Smith</span>.

    <span property="contact:title">Web hacker</span>

    at

    <a rel="contact:org" href="http://example.org">
        Example.org
    </a>.

    You can contact me

    <a rel="contact:email" href="mailto:jo@example.org">
        via email
    </a>.

  </p>
...

Notice how Jo was able to use @rel directly within the anchor element to designate her organization and email address. @rel indicates the type of relationship between the current URI, designated by @about, and the target URI, designated by @href. Specifically, contact:org indicates a relationship of type "vCard organization", while contact:email indicates a relationship of type "vCard email".

For simplicity's sake, we have slightly abused the vCard vocabulary above: vCard technically requires that the type of the email address be specified, e.g. work or home email. In Section 3.4 Layers of Structure — Subresources, we show how rel can be used without a corresponding href, in order to create subresources and provide correct markup for expressing data such as full vCards.

2.4 The Complete XHTML with RDFa

Jo's complete XHTML with RDFa is thus:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">
<html xmlns:cal="http://www.w3.org/2002/12/cal/ical#"
      xmlns:contact="http://www.w3.org/2001/vcard-rdf/3.0#">
  <head>
    <title>Jo's Friends and Family Blog</title>
  </head>
  <body>
...
  <p instanceof="cal:Vevent">
    I'm holding
    <span property="cal:summary">
      one last summer Barbecue,
    </span>
    on
    <span property="cal:dtstart" content="20070916T1600-0500">
      September 16th at 4pm.
    </span>
  </p>
...
  <p class="contactinfo" about="http://example.org/staff/jo">
    <span property="contact:fn">Jo Smith</span>.
    <span property="contact:title">Web hacker</span>
    at
    <a rel="contact:org" href="http://example.org">
      Example.org
    </a>.
    You can contact me
    <a rel="contact:email" href="mailto:jo@example.org">
      via email
    </a>.
  </p>
...
    </body>
</html>

If Jo changes her email address link, her organization, or the description of her event, RDFa parsers will automatically pick up these changes in the marked up, structured data. The only places where this doesn't happen is when @content overrides the value displayed in the element's content, in which case the @content value must be updated along with the displayed value. This limitation is inevitable when human and machine readability are at odds.

(Once again, the RDF-inclined reader will want to consult the resulting RDF triples 4.1 Events and Contact Information.)

2.5 Working Within a Fragment of the XHTML

What if Jo does not have complete control over the XHTML of her blog? For example, she may be using a content management system which makes it particularly difficult to add the vocabularies in the html start-tag without adding it to every page on her site. Or, she may be using a Web provider that doesn't allow her to change the header of the page to begin with.

Fortunately, RDFa uses compact URIs, where prefixes can be declared using standard XML namespace conventions. Thus, vocabularies can be imported "locally" to an XHTML element. Jo's blog page could express the exact same structured data with the following markup:

<html>
  <head>
    <title>Jo's Friends and Family Blog</title>
  </head>
  <body>
...
  <p instanceof="cal:Vevent"
     xmlns:cal="http://www.w3.org/2002/12/cal/ical#">
    I'm holding
    <span property="cal:summary">
      one last summer Barbecue,
    </span>
    on
    <span property="cal:dtstart" content="20070916T1600-0500">
      September 16th at 4pm.
    </span>
  </p>
...
  <p class="contactinfo" about="http://example.org/staff/jo"
     xmlns:contact="http://www.w3.org/2001/vcard-rdf/3.0#">
    <span property="contact:fn">
      Jo Smith
    </span>.
    <span property="contact:title">
      Web hacker
    </span>
    at
    <a rel="contact:org" href="http://example.org">
      Example.org
    </a>.
    You can contact me
    <a rel="contact:email" href="mailto:jo@example.org">
      via email
    </a>.
  </p>
...
  </body>
</html>

In this case, each p only needs one vocabulary: the first uses iCal, the second uses vCard. When needed, more than one vocabulary can be imported into any element, not just html. This makes copying and pasting XHTML with RDFa much easier. In particular, it allows Web widgets to carry their own RDFa in a self-contained manner.

3 Advanced Concepts: Custom Vocabularies, Document Fragments, Complex Data, ...

RDFa can do much more than the simple examples described above. This next section explores some of its advanced capabilities:

3.1 Creating a Custom Vocabulary and Using Compact URIs

All field names and data types in RDFa are URIs, e.g. http://purl.org/dc/elements/1.1/title is the "Dublin Core title" field. In RDFa, we often use compact versions of those URIs, by

  • defining a prefix using XML namespace conventions, and
  • using the prefixed notation to designate the URI.

This helps keep the markup short and clean:

<div xmlns:dc="http://purl.org/dc/elements/1.1/">

   <span property="dc:title">Yowl</span>,

   created by

   <span property="dc:creator">Mark Birbeck</span>.

</div> 

Because concepts are simply URIs, it is trivial to create one's own vocabulary: simply mint new URIs in a domain you control, and use them in RDFa markup. This is, in fact, the power of RDF, RDFa's underlying technology.

Consider a (fictional) photo management Web site called Shutr, whose Web site is http://www.shutr.net. Users of Shutr can upload their photos at will, annotate them, organize them into albums, and share them with the world. They can choose to keep these photos private, or make them available for public consumption under licensing terms of their choosing.

Shutr chooses to mark up its photos with RDFa. Shutr expects that users will be able to easily develop programs that download photo pages marked up with RDFa, extract the structured data, and provide new functionality, e.g. "image newsreaders", family photo-album screensavers, etc. Eventually, RDFa-enabled browsers can even pick up this structured data as the user surfs.

Some structured-data concepts, such as dc:title, dc:date, etc. can be clearly reused from the Dublin Core vocabulary, but other concepts, such as lens settings, camera model, and other photographer parameters, may need to be defined from scratch. For this purpose, Shutr defines a vocabulary namespace URI:

http://shutr.net/vocab/1.0/

Shutr can then publish terms such as http://shutr.net/vocab/1.0/takenWithCamera, http://shutr.net/vocab/1.0/aperture, etc.

The main benefit of RDF is precisely that all vocabulary components are simply URIs. anyone can define a vocabulary, extend it with a few additional concepts, make these new concepts immediately accessible to others, and provide a description of the concept simply by "filling in" the Web page that is returned when the concept URI is accessed. No centralized organization is needed to coordinate the creation and extension of vocabularies: RDF allows one to define relationships (including full equivalence) between concepts that develop organically in the community.

Other publishers can then choose to reuse Shutr's published concepts where they see fit. Using RDF, Shutr can add information about the concepts at each concept's URI, indicating a human-readable description for the concept, what other concepts it may be related to and in what way.

3.2 Qualifying Other Documents and Document Chunks

Shutr may choose to present many photos in a given XHTML page. In particular, at the URI http://www.shutr.net/user/markb/album/12345, all of the album's photos will appear inline. Structured data about each photo can be included simply by specifying @about, which indicates the resource that fields refer to within that XHTML element.

<ul>
  <li> <a href="/user/markb/photo/23456">
         <img src="/user/markb/photo/23456_thumbnail" />
       </a>
  
    <span about="/user/markb/photo/23456"
          property="dc:title">Sunset in Nice</span>
  
  </li>

  <li> <a href="/user/markb/photo/34567">
         <img src="/user/markb/photo/34567_thumbnail" />
       </a>

    <span about="/user/markb/photo/34567"
          property="dc:title">W3C Meeting in Mandelieu</span>

  </li>
</ul>

This same approach applies when the field value is a URI. For example, each photo in the album has a creator and may have its own copyright license. We can use the convenient inheritance of @about to refer to the photo once, then adding as many fields as we want for that photo between the start- and and end-tags of the element with the @about value:

<ul>
  <li about="/user/markb/photo/23456">
    
    <a href="/user/markb/photo/23456">
      <img src="/user/markb/photo/23456_thumbnail" />
    </a>
    
    <span property="dc:title">Sunset in Nice</span>
    
    taken by photographer
    
    <a property="dc:creator"
       href="/user/markb">Mark Birbeck</a>,
    
    licensed under a
    
    <a rel="cc:license"
       href="http://creativecommons.org/licenses/by-nc/3.0/">
      Creative Commons Non-Commercial License
    </a>.
    
  </li>

  <li about="/user/markb/photo/34567">
    
    <a href="/user/markb/photo/34567">
      <img src="/user/markb/photo/34567_thumbnail" /> 
    </a>
    
    <span property="dc:title">W3C Meeting in Mandelieu</span>
    
    taken by photographer
    
    <a property="dc:creator"
       href="/user/stevenp">Steven Pemberton</a>,
    
    licensed under a
    
    <a rel="cc:license"
       href="http://creativecommons.org/licenses/by/3.0/">
         Creative Commons Commercial License
    </a>.
  
  </li>
</ul>

While it makes sense for Shutr to have a whole Web page dedicated to each photo album, it might not make as much sense to have a single page for each camera owned by a user. A single page that describes all cameras belonging to a single user is more appropriate, with the @id XHTML attribute used to designate each camera. RDFa can be used to add structured data in this situation, too.

Consider the page http://www.shutr.net/user/markb/cameras, which, as its URI implies, lists Mark Birbeck's cameras. Its XHTML contains:

<ul>
  <li id="nikon_d200"> Nikon D200, 3 pictures/second.
  </li>

  <li id="canon_sd550"> Canon Powershot SD550, 5 pictures/second.
  </li>
</ul>

and the photo page will then include information about which camera was used to take each photo:

<ul>
  <li>
    <img src="/user/markb/photo/23456_thumbnail" />
    ...
    using the <a href="/user/markb/cameras#nikon_d200">Nikon D200</a>,
    ...
  </li>
...
</ul>

The RDFa syntax for formally specifying the relationship is exactly the same as before, as expected:

<ul>
  <li about="/user/markb/photo/23456">
    ...
    using the <a rel="shutr:takenWithCamera" 
         href="/user/markb/cameras#nikon_d200">Nikon D200</a>,
    ...
  </li>
...
</ul>

Then, the XHTML snippet at http://www.shutr.net/user/markb/cameras is:

<ul>
  <li id="nikon_d200" about="#nikon_d200">
    
    <span property="dc:title">Nikon D200</span>
    
    <span property="shutr:frameRate">3 pictures/second</span>
    
  </li>

  <li id="canon_sd550" about="#canon_sd550">

    <span property="dc:title">Canon Powershot SD550</span>

    <span property="shutr:frameRate">5 pictures/second</span>

  </li>
</ul>

Notice, again, how text can serve both for the human and machine readable versions: there is no need to keep a separate file up-to-date.

The RDF interpretation of the above markup can be found in 4.2 Custom Vocabularies and Datatypes.

3.3 Data Types

When dealing with fields of structured data, one may well want (or need) to specify a data type so that computer programs that read the data can make sense of it. Consider the expression of a date. We have already seen how the human-rendered and machine-readable data may not be the same, and how we can use @content to provide a machine-readable value. Adding a datatype is only one more attribute: @datatype. For example, when expressing the date on which a photo was taken:

<ul>

  <li about="/user/markb/photo/23456">

    ...

    taken on
    <span property="dc:date" content="2007-05-12" datatype="xsd:date">
      May 12th, 2007
    </span>

    ...
        
  </li>

</ul>

RDFa uses XML schema data types [XSD-DT].

The RDF interpretation of the above markup can be found in 4.2 Custom Vocabularies and Datatypes.

3.4 Layers of Structure — Subresources

Sometimes, one may need to mark up a resource with a number of fields, all without giving it a URL, or even a fragment identifier. Consider the case where Shutr decides to let users annotate photos in order to indicate which individuals are depicted in the photo. The barebones XHTML is:

<div>
  This photo depicts Mark Birbeck (mark@example.org) and Steven Pemberton (steven@example.org).
</div>

The simplest way to mark this up without attempting to provide unique identities for photo subjects is to define subresources, effectively new resources that are not given a name. (In RDF, we call these blank nodes.) The following markup will do just that:

<div about="/user/markb/photo/23456">
  This photo depicts

  <span rel="foaf:depicts">
    <span property="foaf:firstname">Mark</span>
    <span property="foaf:lastname">Birbeck</span>
    (<span property="foaf:mbox">mark@example.org</span>)
  </span>
 
  and
 
  <span rel="foaf:depicts">
    <span property="foaf:firstname">Steven</span>
    <span property="foaf:lastname">Pemberton</span>
    (<span property="foaf:mbox">steven@example.org<span>).
  </span>

</div>

If, at one point, the Shutr site adds individual URLs to "name" and further describe subjects of photos, it is trivial to give this subresource a URI by using @href.

<div about="/user/markb/photo/23456">
  This photo depicts

  <span rel="foaf:depicts" href="/models/mark">
    <span property="foaf:firstname">Mark</span>
    <span property="foaf:lastname">Birbeck</span>
    (<span property="foaf:mbox">mark@example.org</span>)
  </span>
 
  and
 
  <span rel="foaf:depicts" href="/models/steven">
    <span property="foaf:firstname">Steven</span>
    <span property="foaf:lastname">Pemberton</span>
    (<span property="foaf:mbox">steven@example.org<span>).
  </span>

</div>

At this point, one may lament the duplication of the @rel. To address this duplication and to make markup more modular, RDFa lets the author move the @rel up one element, at which point @about on a child element completes the @rel:

<div about="/user/markb/photo/23456" rel="foaf:depicts">
  This photo depicts

  <span about="/models/mark">
    <span property="foaf:firstname">Mark</span>
    <span property="foaf:lastname">Birbeck</span>
    (<span property="foaf:mbox">mark@example.org</span>)
  </span>
 
  and
 
  <span about="/models/steven">
    <span property="foaf:firstname">Steven</span>
    <span property="foaf:lastname">Pemberton</span>
    (<span property="foaf:mbox">steven@example.org<span>).
  </span>

</div>

The modularity of the above markup is now clear: Each of the two top-level span elements can be lifted and moved to another location, where it still describes a single photo model, its name, and contact information. Placing the span inside an element with an "incomplete @rel" creates a connection.

The above markup uses the FOAF (Friend-Of-A-Friend) vocabulary which includes the field foaf:depicts that relates a photograph with a person depicted in the photograph. The use of @rel without @href triggers the definition of a new subresource, which is then the value of the foaf:depicts field. Then, all contained markup applies to this new subresource. In RDFa-speak, we call this "chaining," as it allows one to easily chain one resource (e.g. the photo) to a subresource (e.g. each of the two persons depicted).

The RDF interpretation of the above markup can be found in 4.3 Layered Data and Subresources.

3.5 Using @src on img, and the use of @rev

Shutr authors may notice that, in a number of cases, the URI of the photos it displays inline using the img element is actually the same as @about for marking up the photo's fields. In order to minimize markup, RDFa allows authors to make use of @src on an img element: it behaves just like @about. In particular, as indicated in the previous section, @src can complete an incomplete @rel from a parent element.

Consider Mark's profile page on Shutr, which lists all of his albums and cameras. This page will likely include a picture of Mark himself:

<div>
  <h1>Mark Birbeck's Photos</h1>
  <img src="/user/markb/profile_photo.jpg" />
  ...
</div>

Shutr may want to indicate that this is Mark's photo, using the FOAF field foaf:img defined specifically for this purpose. This can be accomplished as follows:

<div about="/user/markb">
  <h1>Mark Birbeck's Photos</h1>
  <span rel="foaf:img">
    <img src="/users/markb/profile_photo.jpg" />
  </span>  
  ...
</div>

Shutr then notes that the profile photo is not only Mark's profile photo, it also happens to depict Mark, since Mark obviously appears in his own profile photo (hopefully). This requires expressing an inverse relationship, where the field is actually added to the image's URI, not to Mark's profile.

For this purpose, RDFa provides @rev, which can be applied to any element where it functions exactly like @rel, except that it expresses the inverse relationship. That is, while @rel tells us that Mark has a FOAF image at /user/markb/profile_photo.jpg, @rev tells us that this /user/markb/profile_photo.jpg depicts Mark.

<div about="/user/markb">
  <h1>Mark Birbeck's Photos</h1>
  <span rel="foaf:img" rev="foaf:depicts">
    <img src="/users/markb/profile_photo.jpg" />
  </span>
  ...
</div>

In other words, Mark has, as his main image, /user/markb/profile_photo.jpg, which of course happens to depict Mark.

The RDF interpretation of the above markup can be found in 4.4 Using @src on img, and the use of @rev.

3.6 Overriding @href and @src

When the displayed content is not quite the correct machine-readable data, we used @content to override it. In some cases, the navigable link is not quite the right machine-readable data, either. Consider, for example, the case where the displayed photo on Mark Birbeck's profile is, in fact, just a thumbnail, while his official FOAF image is the full-sized version. In this case, and in any case where @src appears and needs to be overridden by another URI, the @about attribute can be used.

The XHTML written above can then be transformed to:

<div about="/user/markb">
  <h1>Mark Birbeck's Photos</h1>
  <span rel="foaf:img">
    <img about="/users/markb/profile_photo.jpg"
         src="/users/markb/profile_photo_thumbnail.jpg" />
  </span>
  ...
</div>

Here, the loaded image will use the thumbnail, but an RDFa-aware browser will know that the machine-readable data only cares about the full-sized version specified in @about.

This need to override a human-readable value also occurs in clickable links, where @href may be appropriate for human readers, but not for machines. In that case we use @resource: on an element where both @href and @resource appear, @href is ignored and @resource behaves exactly like @href.

@resource can be particularly useful in cases where the URI is not navigable in any way, e.g. a book's ISBN number represented as URN:ISBN:0-395-36341-1.

The RDF interpretation of this markup can be found in 4.5 Overriding @href and @src

4 RDF Correspondence

RDF [RDF] is the W3C standard for interoperable structured data. Though one need not be versed in RDF to understand the basic concepts of RDFa, it helps to know that RDFa is effectively the embedding of RDF in XHTML.

Briefly, RDF is an abstract generic data model. An RDF statement is a triple, composed of a subject, a predicate, and an object. For example, the following triple has /photos/123 as subject, dc:title as predicate, and the literal "Beautiful Sunset" as object:

  </photos/123> dc:title "Beautiful Sunset" .

A triple effectively relates its subject and object by its predicate: the document /photos/123 has, as title, "Beautiful Sunset". Structured data in RDF is represented as a set of triples. The notation above is called N3 [N3]. URIs are written using angle brackets, literal string values are written in quotation marks, and compact URIs are written directly (with prefixes declared earlier).

A collection of triples is often called a graph because when the same URIs appear as the subjects and objects of multiple triples, the triples can be treated as a collective unit that is greater than the sum of its parts. (While it is not unusual to have a program create a visual representation of one of these graphs, it's actually named after the computer science data structure graph, not the visual presentation of one.)

All subjects and predicates are nodes of such a graph, while objects can be nodes or literal string values. Nodes can be URIs, or they can be blank, in which case they are not addressable by other documents. Blank nodes, denoted _:bnodename, are particularly useful when expressing layered data without having to assign URIs to intermediate nodes.

4.1 Events and Contact Information

In Section 2.2 Publishing An Event, Jo published an event without giving it a URI. The RDF triples extracted from her markup are:

_:blanknode0
   rdf:type cal:Vevent; 
   cal:summary "last summer Barbecue";
   cal:dtstart "20070916T1600-0500" .

In plain English, these triples mean that an unnamed item, _:blanknode0, is a calendar event, with event summary "last summer Barbecue" and start time "20070916T1600-0500".

In Section 2.3 Publishing Contact Information, Jo published contact information. The RDFa is parsed to generate the following RDF triples:

<http://example.org/staff/jo>
   contact:fn "Jo Smith";
   contact:title "Web Hacker";
   contact:org <http://example.org>;
   contact:email <mailto:jo@example.org>.

In plain English, these triples mean that the data item designed by the URL <http://example.org/staff/jo> has full name "Jo Smith", job title "Web Hacker", organization example.org, and email contact jo@example.org.

4.2 Custom Vocabularies and Datatypes

The XHTML+RDFa in the 3.2 Qualifying Other Documents and Document Chunks yields the following triples:

</user/markb/photo/23456> dc:title "Sunset in Nice" .
              
</user/markb/photo/34567> dc:title "W3C Meeting in Mandelieu" .

The more complete example, including licensing information, yields the following triples:

</user/markb/photo/23456>
    dc:title "Sunset in Nice" ;
    dc:creator "Mark Birbeck" ;
    cc:license <http://creativecommons.org/licenses/by-nc/3.0/> .

</user/markb/photo/34567>
    dc:title "W3C Meeting in Mandelieu" ;
    dc:creator "Steven Pemberton" ;
    cc:license <http://creativecommons.org/licenses/by/3.0/> .

The example that links a photo to the camera it was taken with corresponds to the following triple:

</user/markb/photo/23456> shutr:takenWithCamera </user/markb/cameras#nikon_d200> .

while the complete camera descriptions yields:

<#nikon_d200>
  dc:title "Nikon D200" ;
  shutr:frameRate "3 pictures/second" .

<#canon_sd550>
  dc:title "Canon Powershot SD550" ;
  shutr:frameRate "5 pictures/second" .

Finally, @datatype as in 3.3 Data Types indicates a datatype as follows:

</user/markb/photo/23456> dc:date "2007-05-12"^^xsd:date .

4.3 Layered Data and Subresources

The subresources example in 3.4 Layers of Structure — Subresources, with photos annotated with the individuals depicted, correspond to RDF blank nodes as follows:

</user/markb/photo/23456>
    foaf:depicts _:span0 ;
    foaf:depicts _:span1 ;
    
_:span0
    foaf:firstname "Mark" ;
    foaf:lastname "Birbeck" ;
    foaf:mbox "mark@example.org" .

_:span1
    foaf:firstname "Steven" ;
    foaf:lastname "Pemberton" ;
    foaf:mbox "steven@example.org" .

Note specifically how the blank node, in this example, is both the object of a first triple, and the subject of a number of follow-up triples. This is specifically the point of the layered markup approach: to create an unnamed subresource.

Once the markup includes @href or @about to identify the subresources, the RDF triples no longer contain blank nodes:

</user/markb/photo/23456>
    foaf:depicts </models/mark> ;
    foaf:depicts </models/steven> ;
    
</models/mark>
    foaf:firstname "Mark" ;
    foaf:lastname "Birbeck" ;
    foaf:mbox "mark@example.org" .

</models/steven>
    foaf:firstname "Steven" ;
    foaf:lastname "Pemberton" ;
    foaf:mbox "steven@example.org" .

4.4 Using @src on img, and the use of @rev

The use of @src on an image, as per 3.5 Using @src on img, and the use of @rev, yields exactly the same triple as if @src were @about:

</user/markb> foaf:img </user/markb/profile_photo.jpg> .

@rev specifies a triple with the subject and object reversed:

</user/markb> foaf:img </user/markb/profile_photo.jpg> .
    
</user/markb/profile_photo.jpg> foaf:depicts </user/markb> .

4.5 Overriding @href and @src

Where @about is present, as per 3.6 Overriding @href and @src, the same triples are generated, with the value of @about replacing the value of @src. Even though the @src points to /user/markb/profile_photo_thumbnail.jpg, the corresponding triple is:

</user/markb> foaf:img </user/markb/profile_photo.jpg> .

5 Case Studies

A number of RDFa Case Studies are under development and available at http://rdfa.info/rdfa-case-studies/.

6 Acknowledgments

This document is the work of the RDF-in-HTML Task Force, including (in alphabetical order) Ben Adida, Mark Birbeck, Jeremy Carroll, Michael Hausenblas, Shane McCarron, Steven Pemberton, Manu Sporny, Ralph Swick, and Elias Torres. This work would not have been possible without the help of the Semantic Deployment Working Group and its previous incarnation, the Semantic Web Deployment and Best Practices Working Group, in particular chairs Guus Schreiber and David Wood, the XHTML2 Working Group, and Ivan Herman, head of the Semantic Web Activity. Earlier versions of this document were officially reviewed by Gary Ng and David Booth, both of whom provided insightful comments that significantly improved the work. Manu Sporny provided crucial feedback in the end stages.

7 Bibliography

CC
Creative Commons (See http://creativecommons.org.)
DC
Dublin Core Metadata Initiative (See http://dublincore.org.)
FOAF
The Friend of a Friend (FOAF) Project (See http://www.foaf-project.org/.)
HTML-WG
HTML Working Group (See http://www.w3.org/MarkUp/.)
N3
Notation 3 (See http://www.w3.org/DesignIssues/Notation3.html.)
RDF
Resource Description Framework (See http://www.w3.org/RDF/.)
RDFa-USECASES
RDFa Use Cases: Scenarios for Embedding RDF in HTML, W3C Working Draft 30 March 2007, http://www.w3.org/TR/2007/WD-xhtml-rdfa-scenarios-20070330/
RDFa-SYNTAX
RDFa in XHTML: Syntax and Processing, W3C Working Draft 21 February 2008, http://www.w3.org/TR/2008/WD-rdfa-syntax-20080221
RDFHTML
RDF-in-HTML Task Force (See http://www.w3.org/2001/sw/BestPractices/HTML/.)
RDFPRIMER
RDF Primer (See http://www.w3.org/TR/REC-rdf-syntax/.)
SWD-WG
Semantic Web Best Deployment Working Group (See http://www.w3.org/2006/07/SWD/.)
SWBPD-WG
Semantic Web Best Practices and Deployment Working Group (See http://www.w3.org/2001/sw/BestPractices/.)
ICAL-RDF
RDF Calendar Interest Group Note (See http://www.w3.org/TR/rdfcal/.)
VCARD-RDF
Representing vCard Objects in RDF/XML (See http://www.w3.org/TR/vcard-rdf.)
XHTML2-WG
XHTML2 Working Group (See http://www.w3.org/MarkUp/.)
XSD
XML Schema (See http://www.w3.org/XML/Schema.)
XSD-DT
XML Schema Datatypes (See http://www.w3.org/TR/xmlschema-2/.)

Changes

Since the 26 October 2007 Working Draft, this document has changed in two small substantive ways:

Also, one typo was fixed: foaf:decpits to foaf:depicts.