RDF

RDF Extracted Attributes from Styled Elements (RDF-EASE)

Buzzword.org.uk Draft 1 October 2008

This version:
tag:buzzword.org.uk,2008:rdf-ease/spec-20081001
Latest version:
tag:buzzword.org.uk,2008:rdf-ease/spec
Previous version:
tag:buzzword.org.uk,2008:rdf-ease/spec-20080923
Editor:
Toby Inkster

Abstract

GRDDL provides a powerful and robust mechanism for extracting RDF triples from XHTML, and more generally any XML-based markup. By introducing an initial “tidying” stage beforehand, GRDDL can also be applied to HTML. GRDDL enables documents authored using the XHTML class attribute and other semantic XHTML techniques to be transformed to a more formal knowledge representation.

The GRDDL recommendation allows for transformations to be written in any programming language, but only documents the use of XSLT transformations in detail. XSLT is a full Turing-complete programming language, far more powerful and complex than necessary for most GRDDL use cases.

This document describes a simple new document description language “RDF-EASE”, with a familiar syntax that borrows heavily from Cascading Style Sheets (CSS). The document also describes how RDF-EASE can be used as a transformation language for the purpose of GRDDL.

Status of this Document

This document is published by buzzword.org.uk, a web site that hosts various specifications, articles and tools of use to web publishers. This is not a W3C recommendation. It is not even a buzzword.org.uk recommendation yet.

The author welcomes feedback on this draft by e-mail to mail@tobyinkster.co.uk.

Table of Contents

  1. Introduction
  2. RDF-EASE Syntax
  3. RDF-EASE Properties
  4. Linking to RDF-EASE Transformation Sheets
  5. Parsing RDF-EASE and XHTML
  6. Mixing RDF-EASE and RDFa
  1. References
  2. Sample Transformations
  3. Change History
  4. Acknowledgments

1. Introduction

This section is informative.

Ten second sales pitch: CSS is an external file that specifies how your document should look; RDF-EASE is an external file that specifies what your document means.

This document introduces a document description language called “RDF-EASE”, which may be used to transform an XHTML document to RDF triples.

It is intended to act as an alternative to XSLT in the context of GRDDL. XSLT’s functional programming style can make it tricky for a programmer more accustomed to procedural programming to pick up; and even programmers who are comfortable with functional programming may have difficulty with its unusual syntax.

RDF-EASE is a non-Turing-complete language, with a familiar CSS-like syntax, easy for non-programmers to pick up quickly. Like CSS, it allows authors to use a flexible system of selectors to select groups of elements and apply various rules to them. RDF-EASE also borrows from RDFa in defining what these rules mean and how they work together.

This document defines the syntax of RDF-EASE, how it should be used in conjunction with GRDDL, how it may be parsed and suggested best practices for mixing RDF-EASE and RDFa.

2. RDF-EASE Syntax

This section is normative.

The keywords “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in [RFC2119].

The syntax of RDF-EASE is a subset of the syntax described in 4.1 Syntax of [CSS21]. Any valid CSS 2.1 selector is also a valid RDF-EASE selector.

All properties in RDF-EASE begin with the string -rdf-, as per 4.1.2.1 Vendor-specific extensions in [CSS21]. This allows RDF-EASE and CSS to be safely mixed in one file, as CSS parsers should recognise RDF-EASE properties as unknown CSS extensions.

2.1. Syntax Differences With CSS

2.2. Defining CURIE Prefixes

In RDF-EASE, CURIE prefixes are not scoped. They are defined in one or more special blocks with a selector of a single underscore. Within these blocks, any property is taken to be a new prefix being defined. The value must be an IRI conforming to [IRI], optionally quoted in double or single quotes, and required to be prefixed with url( and suffixed with ). An example follows.

_ {
	foaf: url("http://xmlns.com/foaf/0.1/");
	xsd:  url(http://www.w3.org/2001/XMLSchema#);
	dc:   url('http://purl.org/dc/terms/')
}

Figure 2a: Defining CURIE prefixes in RDF-EASE.

For convenience, certain prefixes are predefined, though authors may override them by explicitly declaring the prefix to point to a different URI. The predefined prefixes are:

rdf
http://www.w3.org/1999/02/22-rdf-syntax-ns#
rdfs
http://www.w3.org/2000/01/rdf-schema#
xsd
http://www.w3.org/2001/XMLSchema#

2.3. The RDF-EASE Cascade

In CSS, properties can only take one value, so the cascade is very important. When two CSS rules both match an element, the most “specific” rule is used [CSS21]. In the following example, the element has a width of 10em.

p {
	width: 20em;
}
p.narrow {
	width: 10em;
}
...

<p class="narrow">A narrow paragraph.</p>

Figure 2b: The CSS Cascade.

With RDF-EASE the cascade works slightly differently, in that most RDFa attributes can take a list of multiple values. An element takes a collection of values from all the CSS rules with selectors matching it.

p {
	-rdf-property: "foaf:name";
}
p.name {
	-rdf-property: "vcard:fn";
}
...

<p class="name" property="dc:title">Joe Bloggs</p>

Figure 2c: In this example, the paragraph takes all three values.

For instances where this cascading is not required, and you wish for the more specific rule to completely replace the less specific rule, a reset keyword is available. Adding the reset keyword to a value tells the processor to ignore the input of less specific rules. RDFa attributes hard-coded in the XHTML cannot be reset, as they are more specific than any RDF-EASE rules.

p {
	-rdf-property: "foaf:name";
}
p.name {
	-rdf-property: reset "vcard:fn";
}
...

<p class="name" property="dc:title">Joe Bloggs</p>

Figure 2d: The paragraph has properties vcard:fn and dc:title, but not foaf:name.

2.4. Media Type

RDF-EASE is a subset of CSS, and may be intermixed with CSS. When a mixed RDF-EASE+CSS file is served, a media type of text/css must be used, in accordance with [CSS-MIME]. When a pure RDF-EASE file is served text/x-rdf+css should be used instead.

In HTTP, and other protocols which serve files with a media type, RDF-EASE implementations must ignore any RDF-EASE files not served with one of these two media types.

3. RDF-EASE Properties

This section is normative.

3.1. -rdf-about

-rdf-about
Value:‘document’ | ‘reset’ | ‘normal’ | nearest-ancestor(SELECTOR)
Initial:‘normal’
Applies to:any element
Inherited:no

Setting the RDF-EASE -rdf-about property is equivalent to setting the XHTML about attribute, with a meaning as specified in 2.1. The RDFa Attributes of [RDFA]. RDF-EASE does not offer the ability to specify arbitrary URIs in this attribute, but instead must take one of four values:

document
This is equivalent to setting the XHTML about attribute to the empty string. Any properties found within the element will refer to the document as a whole.
reset
Any -rdf-about properties on less specific RDF-EASE selectors that match this element should be ignored.
normal
This property is a no-op, equivalent to not having set the property at all.
nearest-ancestor(SELECTOR)
Where SELECTOR may be any selector, quoted. A named blank node is created, and associated with the nearest ancestor XHTML element matching the selector specified (and treating all nodes as ancestors of themselves). This property is equivalent to setting the XHTML about attribute to this named blank node.

The “nearest ancestor” feature provides a scoping feature useful for transforming microformats with RDF-EASE. It allows for the following hCards to be parsed as meaning the same thing:

.vcard
{
	-rdf-typeof: "foaf:Person";
}
.vcard .fn
{
	-rdf-property: "foaf:name";
	-rdf-datatype: "xsd:string";
}
.vcard .url
{
	-rdf-rel: "foaf:page";
}
/* This scopes everything within the hCard as applying to the
 * hCard as a whole.
 */
.vcard, .vcard *
{
	-rdf-about: nearest-ancestor(".vcard");
}
		
<div class="vcard">
  <a class="fn url" href="http://example.com">Joe Bloggs</a>
</div>
<div class="vcard">
  <span class="fn"><a class="url" href="http://example.com">Joe Bloggs</a></span>
</div>
<div class="vcard">
  <a class="url" href="http://example.com"><span class="fn">Joe Bloggs</span></a>
</div>

Figure 3a: The importance of the “nearest ancestor” construct.

Without nearest ancestor scoping, in the third hCard, it would be impossible for the foaf:name property to be applied to the person — instead the foaf:name would be taken as applying to the URL.

3.2. -rdf-content

-rdf-content
Value:attr(ATTR) | ‘normal’
Initial:‘normal’
Applies to:any element
Inherited:no

Setting the RDF-EASE -rdf-content property is equivalent to setting the XHTML content attribute, with a meaning as specified in 2.1. The RDFa Attributes of [RDFA]. Rather than setting the XHTML content attribute to a specific string, it is used to specify another attribute from whence to read the content value.

abbr { -rdf-content: attr(title); }

Figure 3b: Example usage of -rdf-content.

The value ‘normal’ is a no-op, equivalent to not having set the property at all.

3.3. -rdf-datatype, -rdf-property, -rdf-rel, -rdf-rev and -rdf-typeof

-rdf-datatype, -rdf-property, -rdf-rel, -rdf-rev, -rdf-typeof
Value:[‘reset’] URI List | ‘normal’
Initial:‘normal’
Applies to:any element
Inherited:no

These last five RDF-EASE properties are equivalent to setting the similarly named XHTML attributes, with a meaning as specified in 2.1. The RDFa Attributes of [RDFA]. The typical value these properties will be set to is a list of tokens, each representing a URI, separated by whitespace. Optionally, the first item in the list may be the token reset instead of a token representing a URI. The value ‘normal’ is a no-op, equivalent to not having set the property at all.

Each token in a URI List should conform to one of the following syntaxes:

CURIE
A compact URI as defined by [CURIE], quoted in either double or single quotes.
For example:
Full IRI
An absolute IRI as defined by [IRI], optionally quoted in either double or single quotes, and required to be prefixed by url( and suffixed by ).
For example:

An example use of these properties:

div.event
{
	-rdf-typeof: "ex:Event";
}
div.event span.starting
{
	-rdf-property: reset "ex:start" "ical:dtstart";
	-rdf-datatype: url('http://www.w3.org/2001/XMLSchema#dateTime') "ex:date-time";
}
div.event span.place
{
	-rdf-rel: reset "ex:location";
	-rdf-rev: reset "ex:event-here";
}

Figure 3c: Example usage of various RDF-EASE properties.

4. Linking to RDF-EASE Transformation Sheets

This section is informative.

Authors should refer to [GRDDL] for normative guidance on how to link to GRDDL transformations in any language.

4.1. rel="transformation"

The easiest way of linking from an XHTML document to an associated RDF-EASE file is to use an XHTML <link /> element in the document head:

<link rel="transformation"
      href="my-semantics.ease"
      type="text/x-rdf+css" />

Figure 4a: Standard method of linking to RDF-EASE transformations.

Because RDF-EASE uses a CSS-compatible syntax, it is possible to intermingle RDF-EASE and CSS in the same file, in which case, you may wish to link to the RDF-EASE file using rel="transformation stylesheet" and type="text/css" to ensure that your file is also used by CSS-capable agents.

Figure 4b: Safe combinations of media types and link types for RDF-EASE transformations.
Media Type Link Type
rel="transformation" rel="stylesheet transformation" rel="stylesheet"
text/css Yes Yes, if file also contains CSS RDF-EASE is ignored
text/x-rdf+css Yes No No

4.2. XHTML Metadata Profiles

@@TODO

5. Parsing RDF-EASE and XHTML

This section is normative.

The following procedure documents an algorithm for parsing an XHTML document with a linked RDF-EASE transformation. In accordance with [GRDDL], when multiple transformations are supplied, each must be applied to the document separately, yielding separate RDF graphs, which may then be merged or “smushed” if desired.

The algorithm modifies the document by adding attributes to various elements, so should be applied to an in-memory copy of the document rather than to the original. The algorithm assumes that the document is held in a DOM-compatible representation, and that the DOM implementation allows for arbitrary attributes to be created for each element, irrespective of whether they are strictly allowed by the document type definition. RDF-EASE implementations may choose to use other algorithms, provided that the triples they produce match the triples produced by the reference algorithm here.

  1. An empty dictionary structure should be created, called CURIEPrefixes. This will store mappings between CURIE prefixes and URIs.

  2. Randomly generate a string to use as a CURIE prefix. It must be a string which is not used as a CURIE prefix anywhere in the document being processed, nor in the RDF-EASE file. The string kwijibo is often a good candidate. We shall refer to this prefix as the kwijibo.

    Add an XML namespace declaration to the document’s root element, defining the namespace kwijibo to be the empty string. e.g.

    <html xmlns:kwijibo="">

    @@ISSUE: according to [XMLNS] this is a completely illegal namespace. The whole idea of kwijibo is really just an ersatz for placing full URIs into RDFa attributes, where they are not allowed. In my implementation, I simply allow them, which works, but requires the parser to break from strict RDFa conformance. There must be a good way around this. Perhaps something like:

    <html xmlns:kwijibohttp="http"
          xmlns:kwijibourn="urn">

    Added after step #6, and after the list of IRI schemes is fully known? Step #2 would still be needed to generate that unique string.

  3. The RDF-EASE file should be parsed, as described in 4. Syntax and basic data types of [CSS21].

    This parsing should yield a collection of CSS rule sets, each of which consists of one or more CSS selectors (such as div.vcard span.fn) and zero or more CSS rules. Each CSS rule consists of a property and value pair.

  4. Any CSS rule sets in the previous collection which contain multiple selectors (separated by comma in the RDF-EASE file), should be split into multiple rule sets, each with the same CSS rules, but each having only a single selector.

  5. The collection of rule sets should be sorted into an ordered list. They must be sorted by specificity of selector, as defined by 6.4.3 Calculating a selector’s specificity of [CSS21], in incresing specificity. When two selectors are of equal specificity, they should be added to the ordered list in the order that they occurred in the RDF-EASE file. Call this list RuleList.

    Rule sets that have a selector of “_” should not be added to RuleList, but instead should be parsed, in the order in which they are specified in the file, as CURIE definition blocks. For each property–value pair, a new definition should be created in CURIEPrefixes, such that the RDF-EASE property is the dictionary key and the RDF-EASE value is the dictionary value.

  6. For each item in RuleList the following procedure should be followed:

    1. A list of elements within the document which match the rule’s selector should be generated. For each element E on this list, the following procedure should be followed:

      1. Each property value pair (p, v) within the rule set should be handled as follows:

        • If p is -rdf-about and v is reset, then the attribute x-rdf-about of element E should be removed if present.

        • If p is -rdf-about and v is document, then the attribute x-rdf-about of element E should be set to the empty string.

        • If p is -rdf-about and v is nearest-ancestor(S), then the following procedure should be followed:

          1. Obtain a list of all nodes within the document matching the selector S.

          2. Within that list, find any nodes such that they are ancestor nodes of E (including E as an ancestor of itself).

          3. Of those ancestor nodes, find the node which is nested most deeply within the DOM tree. Call this anc.

          4. If anc has an about attribute set...

            @@TODO: decide what happens here.

          5. Run anc through a hash function to generate a hexadecimal (or other safe) string. This must be a predictable hash function, such that the same node passed through it will always render the same result. Call this hash H.

          6. Set the x-rdf-about attribute of E to [_:H].

        • If p is -rdf-content and v is reset, then the attribute x-rdf-content of element E should be removed if present.

        • If p is -rdf-content and v specifies an attribute attr(a), then the attribute x-rdf-content of element E should be set to the value of attribute a of element E.

        • If p is one of -rdf-datatype, -rdf-property, -rdf-rel, -rdf-rev or -rdf-typeof (where the part after the -rdf- will be referred to as px) then split v into whitespace delimited tokens, and for each token tok:

          • If tok is reset, then remove attribute x-rdf-px from element E.

          • If tok is a URI, wrapped in url(...) and optionally quoted, then append to the x-rdf-px attribute of element E: a single space character, the kwijibo string, a colon, and then this URI.

          • If tok is a string containing a colon, and optionally quoted, then:

            1. Split token tok on the first colon character yielding two strings, pfx and sfx.

            2. If pfx is defined in CURIEPrefixes then let upfx be the URI that the prefix represents.

            3. If upfx is defined, then append to the x-rdf-px attribute of element E: a single space character, the kwijibo string, a colon, upfx and sfx.

          • Otherwise, tok is ignored. A warning message may be emitted.
        • Otherwise, the property–value pair is ignored. A warning message may be emitted if the RDF-EASE file was served with media type text/x-rdf+css.

  7. For each element in the document, if an x-rdf-about attribute is present:

    1. If the about attribute is not present, then the about attribute is set to be the same as the x-rdf-about attribute.

    2. The x-rdf-about attribute is removed, as it was only ever supposed to be temporary.

  8. For each element in the document, if an x-rdf-content attribute is present:

    1. If the content attribute is not present, then the content attribute is set to be the same as the x-rdf-content attribute.

    2. The x-rdf-content attribute is removed, as it was only ever supposed to be temporary.

  9. For each a from { datatype , property , rel , rev , typeof }:

    1. If there is no attribute x-rdf-a then skip to the next value of a.

    2. If the element does not have an attribute a, then a new attribute a is created as an empty string.

    3. Append the value of x-rdf-a to the attribute a.

    4. The x-rdf-a attribute is removed, as it was only ever supposed to be temporary.

  10. The document is processed to produce triples, as described in 5. Processing Model of [RDFA].

5.1. Example of Processing

This sub-section is informative.

Here is the RDF-EASE being used in the example:

_ {
	foaf: url("http://xmlns.com/foaf/0.1/");
	dc: url("http://purl.org/dc/terms/");
	ex: url("http://example.org/ns#");
}
title {
	-rdf-about: document;
	-rdf-property: "dc:title";
}
li {
	-rdf-typeof: "ex:ListItem";
	-rdf-property: "ex:contents";
}
ul.people li {
	-rdf-typeof: "foaf:Person";
	-rdf-property: reset "foaf:name";
}
ul.people li[title] {
	-rdf-content: attr(title);
}

It is being applied to the following XHTML:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">
<html xml:lang="en"
      xmlns="http://www.w3.org/1999/xhtml"
      xmlns:foaf="http://xmlns.com/foaf/0.1/">
	<head>
		<title>Example RDF-EASE</title>
	</head>
	<body>
		<h1 property="dc:invalid">Example RDF-EASE</h1>
		<h2>A List of People</h2>
		<ul class="people">
			<li>Alice Jones</li>
			<li title="Robert Smith">Bob Smith</li>
			<li property="foaf:nickname">Carol Black</li>
		</ul>
	</body>
</html>

After step #6 in the reference parsing algorithm, the document will look like this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">
<html xml:lang="en"
      xmlns="http://www.w3.org/1999/xhtml"
      xmlns:foaf="http://xmlns.com/foaf/0.1/"
      xmlns:kwijibo="">
	<head>
		<title x-rdf-property=" kwijibo:http://purl.org/dc/terms/title"
		    x-rdf-about="">Example RDF-EASE</title>
	</head>
	<body>
		<h1 property="dc:invalid">Example RDF-EASE</h1>
		<h2>A List of People</h2>
		<ul class="people">
			<li x-rdf-typeof=" kwijibo:http://xmlns.com/foaf/0.1/Person kwijibo:http://example.org/ns#ListItem"
			    x-rdf-property=" kwijibo:http://xmlns.com/foaf/0.1/name"
			    >Alice Jones</li>
			<li title="Robert Smith"
			    x-rdf-content="Robert Smith"
			    x-rdf-typeof=" kwijibo:http://xmlns.com/foaf/0.1/Person kwijibo:http://example.org/ns#ListItem"
			    x-rdf-property=" kwijibo:http://xmlns.com/foaf/0.1/name"
			    >Bob Smith</li>
			<li property="foaf:nickname"
			    x-rdf-typeof=" kwijibo:http://xmlns.com/foaf/0.1/Person kwijibo:http://example.org/ns#ListItem"
			    x-rdf-property=" kwijibo:http://xmlns.com/foaf/0.1/name"
			    >Carol Black</li>
		</ul>
	</body>
</html>

After step #9, this has been reduced to:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">
<html xml:lang="en"
      xmlns="http://www.w3.org/1999/xhtml"
      xmlns:foaf="http://xmlns.com/foaf/0.1/"
      xmlns:kwijibo="">
	<head>
		<title property=" kwijibo:http://purl.org/dc/terms/title"
		    about="">Example RDF-EASE</title>
	</head>
	<body>
		<h1 property="dc:invalid">Example RDF-EASE</h1>
		<h2>A List of People</h2>
		<ul class="people">
			<li typeof=" kwijibo:http://xmlns.com/foaf/0.1/Person kwijibo:http://example.org/ns#ListItem"
			    property=" kwijibo:http://xmlns.com/foaf/0.1/name"
			    >Alice Jones</li>
			<li title="Robert Smith"
			    content="Robert Smith"
			    typeof=" kwijibo:http://xmlns.com/foaf/0.1/Person kwijibo:http://example.org/ns#ListItem"
			    property=" kwijibo:http://xmlns.com/foaf/0.1/name"
			    >Bob Smith</li>
			<li property="foaf:nickname kwijibo:http://xmlns.com/foaf/0.1/name"
			    typeof=" kwijibo:http://xmlns.com/foaf/0.1/Person kwijibo:http://example.org/ns#ListItem"
			    >Carol Black</li>
		</ul>
	</body>
</html>

In step #10, this produces the following triples, expressed using [TURTLE].

@prefix dc   : <http://purl.org/dc/terms/> .
@prefix ex   : <http://example.org/ns#> .
@prefix foaf : <http://xmlns.com/foaf/0.1/> .

<> dc:title "Example RDF-EASE"@en .
_:bnode1 a foaf:Person , ex:ListItem ;
         foaf:name "Alice Jones"@en .
_:bnode2 a foaf:Person , ex:ListItem ;
         foaf:name "Robert Smith"@en .
_:bnode3 a foaf:Person , ex:ListItem ;
         foaf:name "Carol Black"@en ;
         foaf:nickname "Carol Black"@en .

Note:

6. Mixing RDF-EASE and RDFa

This section is informative.

When writing pages, authors need to take care that visual styles specified as XHTML attributes and CSS properties not only work well together, but also work when the CSS is absent. In the following example, the text “Hello world!” is clearly visible as white text on a blue background when CSS is enabled, but invisible white text on a white background if CSS is disabled or unavailable.

<html>
	<head>
		<title>A Contrived Example</title>
		<style type="text/css">
			p { background: blue; }
		</style>
	</head>
	<body bgcolor="white">
		<p>
			<font color="white">Hello world!</font>
		</p>
	</body>
</html>

Figure 6a: Unsafe usage of CSS.

Similarly, authors using RDF-EASE need to check that the RDF triples generated by a pure RDFa parser, which cannot handle RDF-EASE, still make sense. An example where the meaning is radically changed follows — an RDF-EASE parser would infer that Alice knows Bob, whereas a non RDF-EASE tool would parse this as meaning that Alice’s name is “Bob”!

.knows { -rdf-rel: "foaf:knows"; }
...

<div about="#alice">
	<p class="knows">
		<span property="foaf:name">Bob</span>
	</p>
</div>

Figure 6b: Unsafe usage of RDF-EASE.

6.1. Safe Combinations

RDF-EASE is capable of specifying any combination of the subject, predicate and object of an RDF triple. But only certain combinations are provably safe to combine.

Figure 6c: Table illustrating combinations of RDFa and RDF-EASE which will normally be safe.
Method of Specifying Resource Behaviour of Parser Safe?
Subject Predicate Object RDFa Parser RDF-EASE Parser
RDFa RDFa RDFa parsed parsed Yes
RDFa RDFa RDF-EASE misinterpreted parsed No
RDFa RDF-EASE RDFa ignored parsed Yes
RDFa RDF-EASE RDF-EASE ignored parsed Yes
RDF-EASE RDFa RDFa misinterpreted parsed No
RDF-EASE RDFa RDF-EASE misinterpreted parsed No
RDF-EASE RDF-EASE RDFa ignored parsed Yes
RDF-EASE RDF-EASE RDF-EASE ignored parsed Yes

For styling, there is a “rule of thumb” that says “whenever you set a foreground colour, set a background colour.” The equivalent rule to combine RDF-EASE with RDFa is “whenever you use an RDFa property, rel or rev attribute, make sure the subject and object of the triple can be determined through pure RDFa.”

Appendix A. References

CONCEPTS
Resource Description Framework (RDF): Concepts and Abstract Syntax, Graham Klyne, Jeremy J Carroll, Editors, Brian McBride, Series editor, W3C Recommendation 10 February 2004 <http://www.w3.org/TR/2004/REC-rdf-concepts-20040210/>. Latest version <http://www.w3.org/TR/rdf-concepts/>.
CSS-MIME
The text/css Media Type, Håkon Wium Lie, Bert Bos, Chris Lilley, RFC 2318 <http://www.rfc-editor.org/rfc/rfc2318.txt>.
CSS21
Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification, Bert Bos, Tantek Çelik, Ian Hickson, Håkon Wium Lie, Editors, W3C Candidate Recommendation 19 July 2007 <http://www.w3.org/TR/2007/CR-CSS21-20070719>. Latest version <http://www.w3.org/TR/CSS21>.
CURIE
CURIE Syntax 1.0, Mark Birbeck, Shane McCarron, Editors, W3C Working Draft 6 May 2008 <http://www.w3.org/TR/2008/WD-curie-20080506>. Latest version <http://www.w3.org/TR/curie>.
GRDDL
Gleaning Resource Descriptions from Dialects of Languages (GRDDL), Dan Connolly, Editor, W3C Recommendation 11 September 2007 <http://www.w3.org/TR/2007/REC-grddl-20070911/>. Latest version <http://www.w3.org/TR/grddl/>.
IRI
Internationalized Resource Identifiers (IRI), Martin Dürst, Michel Suignard, RFC 3987 <http://www.rfc-editor.org/rfc/rfc3987.txt>.
RDFA
RDFa in XHTML: Syntax and Processing, Ben Adida, Mark Birbeck, Shane McCarron, Steven Pemberton, Editors, W3C Proposed Recommendation 4 September 2008 <http://www.w3.org/TR/2008/PR-rdfa-syntax-20080904>. Latest version <http://www.w3.org/TR/rdfa-syntax>.
RFC2119
Key words for use in RFCs to Indicate Requirement Levels, Scott Bradner, RFC 2119 <http://www.rfc-editor.org/rfc/rfc2119.txt>.
TURTLE
Turtle: Terse RDF Triple Language, David Beckett, Tim Berners-Lee, W3C Team Submission 14 January 2008 <http://www.w3.org/TeamSubmission/2008/SUBM-turtle-20080114/>. Latest version <http://www.w3.org/TeamSubmission/turtle/>.
URI
Uniform Resource Identifiers (URI): Generic Syntax, Tim Berners-Lee et al, RFC 3986 <http://www.rfc-editor.org/rfc/rfc3986.txt>.
XHTML
XHTML™ 1.0 The Extensible HyperText Markup Language (Second Edition), W3C HTML Working Group, W3C Recommendation 26 January 2000, revised 1 August 2002 <http://www.w3.org/TR/2002/REC-xhtml1-20020801>. Latest version <http://www.w3.org/TR/xhtml1>.

Appendix B. Sample Transformations

This section is informative.

hAudio

_ {
	audio: url("http://purl.org/media/audio#");
	comm:  url("http://purl.org/commerce#");
	dc:    url("http://purl.org/dc/terms/");
	foaf:  url("http://xmlns.com/foaf/0.1/");
	media: url("http://purl.org/media#");
}
.haudio {
	-rdf-typeof: "audio:Recording";
	-rdf-about: nearest-ancestor(".haudio");
}
.haudio * {
	-rdf-about: nearest-ancestor(".haudio");
}
.haudio .fn {
	-rdf-property: "dc:title" "rdfs:label";
	-rdf-datatype: "xsd:string";
}
.haudio .album {
	-rdf-property: "dc:isPartOf";
	-rdf-datatype: "xsd:string";
}
.haudio .category {
	-rdf-property: "dc:type";
	-rdf-datatype: "xsd:string";
}
.haudio .contributor {
	-rdf-property: "dc:contributor";
	-rdf-datatype: "xsd:string";
}
.haudio .description {
	-rdf-property: "dc:description";
	-rdf-datatype: "xsd:string";
}
.haudio .position {
	-rdf-property: "media:position";
	-rdf-datatype: "xsd:integer";
}
.haudio .photo {
	-rdf-rel: "media:depiction" "foaf:depiction";
}
.haudio .price {
	-rdf-property: "comm:costs";
	-rdf-datatype: "xsd:string";
}
.haudio *[rel=~"enclosure"] {
	-rdf-rel: "media:download";
}
.haudio *[rel=~"payment"] {
	-rdf-rel: "comm:payment";
}
.haudio *[rel=~"sample"] {
	-rdf-rel: "media:sample";
}
.haudio .url {
	-rdf-rel: "foaf:page";
}
.haudio .item {
	-rdf-rel: "media:contains" "dc:hasPart";
	-rdf-rev: "dc:isPartOf";
	-rdf-about: nearest-ancestor(".haudio .item");
}
.haudio .item * {
	-rdf-about: nearest-ancestor(".haudio .item");
}

Appendix C. Change History

I will start noting changes to this draft has been published to an HTTP URI.

Appendix D. Acknowledgments

@@TODO