Copyright © 2007 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C liability, trademark and document use rules apply.
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.
This document is an introduction to RDFa, a method for achieving precisely this kind of structured data embedding in XHTML. The normative specification of RDFa may be found in [RDFa-SYNTAX].
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 former W3C HTML Working Group, now called 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 substantial update to the previous version, representing several design changes since the previous version was published. These 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 includes 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.
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
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]:
dc
: http://purl.org/dc/elements/1.1/foaf
: http://xmlns.com/foaf/0.1/cc
:
http://creativecommons.org/ns#xsd
:
http://www.w3.org/2001/XMLSchema# 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 [RDFa-USECASES]. For in-depth details on RDFa, including how to implement an RDFa parser, the reader should consult [RDFa-SYNTAX].
Jo keeps a private blog for her friends and family.
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.
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.)
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.
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.)
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.
RDFa can do much more than the simple examples described above. This next section explores some of its advanced capabilities:
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
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.
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.
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.
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>
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.
@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 @href
.
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>
<img rel="foaf:img" src="/users/markb/profile_photo.jpg" />
...
</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 img
or any other element. @rev
functions much like @rel
, except the direction of the relationship is reversed. 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>
<img rel="foaf:img" rev="foaf:depicts"
src="/user/markb/profile_photo.jpg" />
...
</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.
@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
@href
or @src
appears and needs to be overridden by
another URI, another RDFa attribute, @resource
, is used.
The XHTML written above can then be transformed to:
<div about="/user/markb">
<h1>Mark Birbeck's Photos</h1>
<img rel="foaf:img"
resource="/user/markb/profile_photo.jpg"
src="/user/markb/profile_photo_thumbnail.jpg" />
...
</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 @resource
.
@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
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.
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
.
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 .
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:decpits _: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.
@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 @href
:
</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> .
@href
and @src
Where @resource
is present, as per 3.6 Overriding @href and @src, the same triples are generated, with the value of @resource
replacing the value of @href
. Even though the @href
points to /user/markb/profile_photo_thumbnail.jpg
, the corresponding triple is:
</user/markb> foaf:img </user/markb/profile_photo.jpg> .
A number of RDFa Case Studies are under development and available at http://rdfa.info/rdfa-case-studies/
.
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, 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.
Since Working Draft #3 of this document:
class
attribute is no longer used to indicate rdf:type
, as this was found to be too confusing. We now use the new instanceof
attribute.