W3C

RDF/A Syntax

A collection of attributes for layering RDF on XML languages

note 11 October 2004

This version:
Editors:
Mark Birbeck, x-port.net Ltd. <Mark.Birbeck@x-port.net>
Steven Pemberton, CWI

Abstract

The aim of this document is to outline a syntax for layering RDF information on any XML document, via attributes.

Status of this Document

This is an internal working draft.

Last Modified: 2004-09-22

Table of Contents

1 Motivation
2 Terms and Abbreviations
    2.1 Namespaces
    2.2 RDF Terminology
        2.2.1 N-Triples
    2.3 Using xml:base
3 Introduction to the structure of RDF/A
    3.1 General Approach
    3.2 Using RDF/A in other namespace documents
    3.3 Global statements
    3.4 Qualifying statements
    3.5 Mixing global and qualifying statements
4 RDF/A in detail
    4.1 Processing
    4.2 Establishing the subject
        4.2.1 Using the about attribute
        4.2.2 Using the attribute nodeID
        4.2.3 Using an attribute of type xml:id
        4.2.4 Using the [context statement]s subject
            4.2.4.1 Using the [context statement]'s nodeID attribute
            4.2.4.2 Using the [context statement]'s about attribute
            4.2.4.3 Using the [context statement]'s id attribute
            4.2.4.4 Generating implicit [unique anonymous ID]s
    4.3 Establishing the predicate
        4.3.1 Using the property attribute
        4.3.2 Using the rel attribute
        4.3.3 Using the rev attribute
        4.3.4 Using the [context statement]'s predicate
            4.3.4.1 Using the [context statement]'s predicate
            4.3.4.2 Using hasReferenceTo
    4.4 Establishing the object
        4.4.1 Using the content attribute
        4.4.2 Using the href attribute
        4.4.3 Providing an object to the [context statement]
    4.5 Summary
5 RDF Concepts
    5.1 Literals as Objects
        5.1.1 Plain Literals
            5.1.1.1 Language Tags
        5.1.2 Typed Literals
            5.1.2.1 XML Literals
    5.2 Blank nodes
6 Examples
    6.1 Creative Commons
7 Rules
8 Bibliography


1 Motivation

Issue (i2):

The syntax is almost complete, but there are still some issues to resolve now that we have tried to 'bridge' the 'clickable and semantic webs'.

The main issue is in determining when some element is providing mark-up for its parent element (what we have called the [context statement]) and when it is providing mark-up for itself. For example, in this statement:

<blockquote rel="dc:source" href="...">
    ...
</blockquote>
                    

we are obviously saying something about the quote's origin. Similarly here, we probably mean the same thing:

<blockquote>
    <link rel="dc:source" href="..." />
    ...
</blockquote>
                    

This latter example 'works' because link has a default style of display: none;. A natural extension would be to provide a live link to the source of the quote:

<blockquote>
    <a rel="dc:source" href="...">Source</a>
    ...
</blockquote>
                    

which we would probably want to mean the same thing as the earlier examples. This is OK, but the problem is that there is no obvious way to differentiate this structure from the earlier one with blockquote. We do have two or three suggestions as to how to solve this, which will be presented separately.

Resolution:

None recorded.

RDF/XML [RDF-SYNTAX] provides sufficient flexibility to represent all of the abstract concepts in RDF [RDF-CONCEPTS]. However, it presents two challenges; first it is difficult or impossible to validate documents that contain RDF/XML using XML Schemas or DTD's, which makes it difficult to import RDF/XML into other markup languages. Whilst newer schema languages such as RELAX NG [RELAXNG] do provide a way to validate documents that contain arbitrary RDF/XML, it will be a while before they gain wide support.

The second challenge is that the syntax of RDF/XML is too unwieldy for use as a mechanism for adding metadata to a document about the document itself. RDF/XML's primary purpose is as a document format for transporting RDF, and it fulfills this role admirably. But when we have a document of some other type -- XHTML, SVG, SSML, and so on -- to which we would like to add arbitrary metadata, RDF/XML is awkward to use.

The resolution is usually to 'hard-wire' attributes directly into the XML language, to represent specific concepts. For example, in XHTML 1.1 and HTML there is a cite attribute. The attribute allows an author to add information to a document to indicate the origin of a quote. The following example comes from [HTML], although it has been reformatted as XHTML [XHTML]:

<blockquote cite="http://www.mycom.com/tolkien/twotowers.html">
    <p>They went in single file, running like hounds on a strong scent,
    and an eager light was in their eyes. Nearly due west the broad
    swath of the marching Orcs tramped its ugly slot; the sweet grass
    of Rohan had been bruised and blackened as they passed.</p>
</blockquote>
            

The problem here is that we have had to add a specific attribute to designate citation, and further, both the browser and some metadata processor need to have knowledge of this attribute, and its position within the mark-up.

The RDF/XML solution is to take the citation out as a specific statement about the quote. Our source document may now look like this:

<blockquote id="q1">
    <p>They went in single file, running like hounds on a strong scent,
    and an eager light was in their eyes. Nearly due west the broad
    swath of the marching Orcs tramped its ugly slot; the sweet grass
    of Rohan had been bruised and blackened as they passed.</p>
</blockquote>
            

and the RDF/XML looks like this:

<rdf:Description about="#q1">
    <xh11:cite href="http://www.mycom.com/tolkien/twotowers.html" />
</rdf:Description>
            

Whilst this approach gives unlimited flexibility, it has not been widely adopted outside the RDF community. It is certainly more difficult for an SVG or HTML author to learn, and so their documents tend to contain little 'extra' metadata. The motivation of RDF/A was to devise a means by which documents could be augmented with metadata, using property values from the growing range of available taxonomies. In RDF/A, one way that the example given above could be marked-up is as follows:

<blockquote>
    <link rel="dc:source" href="http://www.mycom.com/tolkien/twotowers.html" />
    <p>They went in single file, running like hounds on a strong scent,
    and an eager light was in their eyes. Nearly due west the broad
    swath of the marching Orcs tramped its ugly slot; the sweet grass
    of Rohan had been bruised and blackened as they passed.</p>
</blockquote>
            

We feel this proposal contributes to standardisation, and takes the pressure off language authors to anticipate all the metadata requirements users of their language might have -- in this example we have used "source" from the Dublin Core [DC] list, rather than inventing our own citation attribute which would be unknown to other languages. For example, the source could still be determined if the same quote were marked-up in SVG:

<svg:text>
    <link rel="dc:source" href="http://www.mycom.com/tolkien/twotowers.html" />
    They went in single file, running like hounds on a strong scent,
    and an eager light was in their eyes. Nearly due west the broad
    swath of the marching Orcs tramped its ugly slot; the sweet grass
    of Rohan had been bruised and blackened as they passed.
</svg:text>
            

We feel these aspects of our proposal are crucial to the future of the Semantic Web, and the place of mark-up documents within it.

This proposal therefore outlines a new XML syntax for RDF that relies only on XML attributes, and so can be easily imported into other markup languages allowing them to carry arbitrary RDF.

2 Terms and Abbreviations

2.1 Namespaces

In the following examples, for brevity assume that the following namespace prefixes are defined:
cc:http://web.resource.org/cc/
dc:http://purl.org/dc/elements/1.1/
ex:http://example.org/
foaf:http://xmlns.com/foaf/0.1/
rdf:http://www.w3.org/1999/02/22-rdf-syntax-ns#
rdfs:http://www.w3.org/2000/01/rdf-schema#
svg:http://www.w3.org/2000/svg
xh11:http://www.w3.org/1999/xhtml
xsd:http://www.w3.org/2001/XMLSchema#

2.2 RDF Terminology

This document uses the following terminology defined in [RDF-CONCEPTS]:

  • URI reference

  • literal

  • plain literal

  • typed literal

  • XML literal

  • XML value

  • node

  • blank node

  • triple

  • RDF graph

We also add two further concepts, an [RDF/A element] and the [context statement] both of which are explained in the processing section.

The aim of RDF/A is to allow [RDF graph]s to be carried in XML documents of any type. An [RDF graph] comprises [node]s linked by relationships. The basic unit of a graph is a [triple], in which a subject [node] is linked to an object [node] via a [predicate]. The subject [node] is always either an [RDF URI reference] or a [blank node], the predicate is always an [RDF URI reference], and the object of a statement can be an [RDF URI reference], a [literal], or a [blank node].

In RDF/A, an [RDF URI reference] is indicated using the attribute about and predicates are represented using one of the attributes property, rel, or rev. Objects which are [RDF URI reference]s are represented using the attribute href, whilst objects that are [literal]s are represented either with the attribute content, or the content of the element in question.

2.2.1 N-Triples

Most of the examples in this document are shown translated into N-Triples [N-TRIPLES] syntax, with a slight variation in that QNames can be used to replace a URI reference. To tell them apart, the QName will have no angle brackets, e.g. the triple:

<http://internet-apps.blogspot.com/> dc:creator "Mark Birbeck" .
                    

should be read as an abbreviation for the N-Triples syntax:

<http://internet-apps.blogspot.com/> <http://purl.org/dc/elements/1.1/creator> "Mark Birbeck" .
                     

Datatypes can also be abbreviated, so the following:

<> dc:title "E = mc<sup>2</sup>: The Most Urgent Problem of Our Time"^^rdf:XMLLiteral .
                    

should be read as an abbreviation for this N-Triples statement:

<> <http://purl.org/dc/elements/1.1/creator> "E = mc<sup>2</sup>: The Most Urgent Problem of Our Time"^^<http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral> .
                     

2.3 Using xml:base

All [RDF URI references] are subject to xml:base[XML-BASE]. Note that this means that in the absence of an xml:base attribute, the document containing the RDF statements is itself the base.

An example follows to show how xml:base affects the subject:

<span xml:base="http://internet-apps.blogspot.com/">
    <link about="" rel="dc:creator" href="http://www.blogger.com/profile/1109404">
        <meta property="dc:title" content="Internet Applications" />
    </link>
</span>
                

The triples generated would be as follows:

<http://internet-apps.blogspot.com/> dc:creator <http://www.blogger.com/profile/1109404> .
<http://internet-apps.blogspot.com/> dc:title "Internet Applications" .
                

3 Introduction to the structure of RDF/A

3.1 General Approach

The main idea behind the syntax for RDF/A is that it should be possible to represent a [triple] using only one XML element. In this way it owes more to 'flat' syntaxes like RDF/N3 [N3-PRIMER] than it does to RDF/XML [RDF-SYNTAX], despite its use of XML.

RDF/A provides a set of attributes that can be used to indicate the different parts of a [triple] on an element. For example, to indicate the creator of the blog 'Internet Applications' (using the Dublin Core taxonomy), we could use one of the following constructs:

<meta about="http://internet-apps.blogspot.com/" property="dc:creator" content="Mark Birbeck" />
                

or:

<link about="http://internet-apps.blogspot.com/" rel="dc:creator" href="http://www.blogger.com/profile/1109404" />
                

or:

 <link about="http://www.blogger.com/profile/1109404" rev="dc:creator" href="http://internet-apps.blogspot.com/" />
                

Each of these statements contains a subject, predicate and object. In the case where the predicate is designated by property the object is a [plain literal], whilst in the case of rel or rev the object is an [RDF URI reference]. The [triple]s generated from these examples are:

<http://internet-apps.blogspot.com/> dc:creator "Mark Birbeck" .
<http://internet-apps.blogspot.com/> dc:creator <http://www.blogger.com/profile/1109404> .
<http://internet-apps.blogspot.com/> dc:creator <http://www.blogger.com/profile/1109404> .
                

Note that the second and third examples generate exactly the same [triple]s. This is because when rev is used for the predicate, a [triple] is generated with the subject and object reversed.

It is also perfectly valid to have both attributes on the same element:

<link
 about="http://internet-apps.blogspot.com/"
    rel="dc:creator" rev="foaf:homepage" href="http://www.blogger.com/profile/1109404"
/>
                

If both attributes are provided -- as in this example -- then two [triple]s are generated, as follows:

<http://internet-apps.blogspot.com/> dc:creator <http://www.blogger.com/profile/1109404> .
<http://www.blogger.com/profile/1109404> foaf:homepage <http://internet-apps.blogspot.com/> .
                

And it's also possible to go further and add the attributes used for denoting statements in which the object is a [literal]. For example:

<link
 about="http://internet-apps.blogspot.com/"
    rel="dc:creator" rev="foaf:homepage" href="http://www.blogger.com/profile/1109404"
    property="dc:title" content="Internet Applications"
/>
                

The triples generated would be as follows:

<http://internet-apps.blogspot.com/> dc:creator <http://www.blogger.com/profile/1109404> .
<http://www.blogger.com/profile/1109404> foaf:homepage <http://internet-apps.blogspot.com/> .
<http://internet-apps.blogspot.com/> dc:title "Internet Applications" .
                

It's possible to do all of this without ambiguity, since the property attribute always denotes a predicate in a statement in which the object is a [literal], whilst the rel and rev attributes always denote a predicate in a statement in which the object is a [URI reference]. Put a different way, property always works with content, whilst rel and rev work with href.

Note:

This last example illustrates that although in this document we generally use meta to designate statements about [literal]s and link to designate statements about [RDF URI reference]s this is merely a convention, and it is in fact the attributes that do all the work, not the elements that contain them.

A second feature of RDF/A is that it is possible to use parts of the host document to provide the [subject] of a [triple]. This marks RDF/A from other approaches to serialising RDF, in that the the same syntax can now be used to make statements about parts of a document, and external documents.

Although it is possible to make these statements using the syntax introduced in the examples above, we provide an alternative -- and more flexible -- approach. For example, we could simply indicate the source of a quote using the following mark-up:

<html xmlns:dc="http://purl.org/dc/elements/1.1/">
    <head>
        <title>On <em>Crime and Punishment</em></title>
        <link about="#q1" rel="dc:source" href="urn:isbn:0140449132" />
    </head>
    <body>
        <blockquote id="q1">
            <p>
                Rodion Romanovitch! My dear friend! If you go on in this way
                you will go mad, I am positive! Drink, pray, if only a few drops!
            </p>
        </blockquote>
    </body>
</html>
                

However, RDF/A provides another mechanism, which is that if a link or meta element is used, and no [subject] is present, then the [triple] concerns the parent of the element. This allows the example above to be recast as follows:

<html xmlns:dc="http://purl.org/dc/elements/1.1/">
    <head>
        <title>On <em>Crime and Punishment</em></title>
    </head>
    <body>
        <blockquote id="q1">
            <link rel="dc:source" href="urn:isbn:0140449132" />
            <p>
                Rodion Romanovitch! My dear friend! If you go on in this way
                you will go mad, I am positive! Drink, pray, if only a few drops!
            </p>
        </blockquote>
    </body>
</html>
	                    

This syntax only applies to the elements link and meta, which means that even without an id attribute, the following statement is still 'about' the blockquote element, and not the body element:

    <blockquote rel="dc:source" href="urn:isbn:0140449132">
        <p>
            Rodion Romanovitch! My dear friend! If you go on in this way
            you will go mad, I am positive! Drink, pray, if only a few drops!
        </p>
    </blockquote>
	                    

3.2 Using RDF/A in other namespace documents

Although originally motivated for XHTML 2 The attributes and elements described in this document allow metadata to be layered onto XML elements from other namespaces. A typical example -- shown above -- might be to describe the source of a quote in an XHTML document:

<html xmlns:dc="http://purl.org/dc/elements/1.1/">
    <head>
        <title>On <em>Crime and Punishment</em></title>
    </head>
    <body>
        <blockquote rel="dc:source" href="urn:isbn:0140449132">
            <p>
                Rodion Romanovitch! My dear friend! If you go on in this way
                you will go mad, I am positive! Drink, pray, if only a few drops!
            </p>
        </blockquote>
    </body>
</html>
                

If more than one piece of metadata needs to be attached to the same element, then the attributes can be attached to child elements. Although any elements could be used to carry the attributes, in this document we generally use the elements meta and link, so as to highlight whether the statement is about a [literal] or a [URI reference]:

<html xmlns:dc="http://purl.org/dc/elements/1.1/">
    <head>
        <title>On <em>Crime and Punishment</em></title>
    </head>
    <body>
        <blockquote>
            <link rel="dc:source" href="urn:isbn:0140449132" />
            <meta property="dc:creator" content="Fyodor Dostoevsky" />
            <p>
                Rodion Romanovitch! My dear friend! If you go on in this way
                you will go mad, I am positive! Drink, pray, if only a few drops!
            </p>
        </blockquote>
    </body>
</html>
                

Now we have attached two pieces of metadata to the blockquote element -- the source of the quote, and its author.

Note:

We say nothing here about how this metadata is used. In the previous example, the information may be of use to an RDF/A-aware browser, and it could be made available to the user accessing the page via a mechanism such as tooltips. But it may also be the case that the document is parsed by some external processor and the output stored as a set of [triple]s. In the latter case the [triple]s generated by the previous example would have a [unique anonymous ID] as the subject of each statement, as follows:

_:a dc:source <urn:isbn:0140449132> .
_:a dc:creator "Fyodor Dostoevsky" .
                    

3.3 Global statements

The previous section shows two types of [RDF/A statement]s. The first is a [global statement], which is self-contained, in that it produces a complete [triple]. It is possible to place this statement anywhere in the containing document, and still generate the same [triple].

This is illustrated in the following two examples; the first locates the metadata statement inside the actual quote:

<html xmlns:dc="http://purl.org/dc/elements/1.1/">
    <head>
        <title>On <em>Crime and Punishment</em></title>
    </head>
    <body>
        <blockquote>
            <meta about="urn:isbn:0140449132" property="dc:creator" content="Fyodor Dostoevsky" />
            <p>
                Rodion Romanovitch! My dear friend! If you go on in this way
                you will go mad, I am positive! Drink, pray, if only a few drops!
            </p>
        </blockquote>
    </body>
</html>
                

whilst the second places it in the head element:

<html xmlns:dc="http://purl.org/dc/elements/1.1/">
    <head>
        <title>On <em>Crime and Punishment</em></title>
        <meta about="urn:isbn:0140449132" property="dc:creator" content="Fyodor Dostoevsky" />
    </head>
    <body>
        <blockquote>
            <p>
                Rodion Romanovitch! My dear friend! If you go on in this way
                you will go mad, I am positive! Drink, pray, if only a few drops!
            </p>
        </blockquote>
    </body>
</html>
                

The [triple]s generated are in both cases:

<urn:isbn:0140449132> dc:creator "Fyodor Dostoevsky" .
                

For an [RDF/A statement] using link or meta to be a [global statement], a subject must be present, otherwise it is a [qualifying statement] (see below). However, if any other element is used in a [RDF/A statement] then the statement will always be a [global statement]. For example:

<html xmlns:dc="http://purl.org/dc/elements/1.1/">
    <head>
        <title>On <em>Crime and Punishment</em></title>
    </head>
    <body>
        <blockquote rel="dc:source" href="urn:isbn:0140449132">
            <p>
                Rodion Romanovitch! My dear friend! If you go on in this way
                you will go mad, I am positive! Drink, pray, if only a few drops!
            </p>
        </blockquote>
    </body>
</html>
                

Here the blockquote element has no subject, but since it is neither link nor meta, the predicate and object refer to the element itself, and so an anonymous node is created:

_:a dc:source <urn:isbn:0140449132> .
                

Note:

The idea that it does not matter where [global statement]s appear in the document is true even if the [global statement] is contained within a link or meta element. The following two sets of mark-up therefore generate exactly the same [triple]s:

<link about="mailto:daniel.brickley@bristol.ac.uk" rel="foaf:knows" href="mailto:libby.miller@bristol.ac.uk" />
<link about="mailto:libby.miller@bristol.ac.uk" rel="foaf:knows" href="mailto:ian.sealy@bristol.ac.uk" />
                    
<link about="mailto:daniel.brickley@bristol.ac.uk" rel="foaf:knows" href="mailto:libby.miller@bristol.ac.uk">
    <link about="mailto:libby.miller@bristol.ac.uk" rel="foaf:knows" href="mailto:ian.sealy@bristol.ac.uk" />
</link>
                    

3.4 Qualifying statements

The second type of statement shown in the previous section is a [qualifying statement]. This is a statement that cannot stand on its own, but provides information about its parent element. It was illustrated in the previous section by the following example:

<html xmlns:dc="http://purl.org/dc/elements/1.1/">
    <head>
        <title>On <em>Crime and Punishment</em></title>
    </head>
    <body>
        <blockquote>
            <link rel="dc:source" href="urn:isbn:0140449132" />
            <meta property="dc:creator" content="Fyodor Dostoevsky" />
            <p>
                Rodion Romanovitch! My dear friend! If you go on in this way
                you will go mad, I am positive! Drink, pray, if only a few drops!
            </p>
        </blockquote>
    </body>
</html>
                

A [qualifying statement] is any statement made using meta or link that does not have a subject. This means that the subject will be derived in some way from the parent element.

3.5 Mixing global and qualifying statements

Further metadata is often available to qualify a statement that has been made. In the previous example we said that a quote is from the book Crime and Punishment, and that the quote was by Dostoevsky:

<blockquote>
    <link rel="dc:source" href="urn:isbn:0140449132" />
    <meta property="dc:creator" content="Fyodor Dostoevsky" />
    <p>
        Rodion Romanovitch! My dear friend! If you go on in this way
        you will go mad, I am positive! Drink, pray, if only a few drops!
    </p>
</blockquote>
                

However, we could have more accurately indicated the origin of the quote, and then gone on to add that the book was written by Dostoevsky:

<blockquote>
    <link rel="dc:source" href="urn:isbn:0140449132" />
    <meta about="urn:isbn:0140449132" property="dc:creator" content="Fyodor Dostoevsky" />
    <p>
        Rodion Romanovitch! My dear friend! If you go on in this way
        you will go mad, I am positive! Drink, pray, if only a few drops!
    </p>
</blockquote>
                

Now our triples would be as follows:

_:a dc:source <urn:isbn:0140449132> .
<urn:isbn:0140449132> dc:creator "Fyodor Dostoevsky" .
                

In this example, the [qualifying statement] does not depend on the [global statement] in any way, which means that the meta element (the [global statement]) could be placed anywhere in the document to obtain the same [triple]s.

4 RDF/A in detail

In this section we look in more detail at the [triple]s that are generated when using RDF/A attributes and elements. We've already said that the aim is to make it possible to generate a [triple] with one element. However, we also saw that if our various attributes and elements are used as children of some element then they augment that element with their values. We therefore need to understand how the subject, predicate and object parts of a [triple] are established from our syntax.

4.1 Processing

An [RDF/A element] is defined as any XML element that contains one or more RDF/A attributes. Processing proceeds by examining each [RDF/A element] in turn. The [RDF/A element] under consideration at any time is the [current statement], and its parent element is the [context statement]. Note that the [context statement] does not need to be an [RDF/A element].

As each [RDF/A element] is examined the processor tries to establish as many sets of subject, predicate and object -- based on the the rules outlined in the remainder of this section -- as it can. For each set established a triple is generated, so whilst this means that more than one triple might be generated for an [RDF/A element], it is also valid for no [triple]s to be generated. This allows certain useful abbreviations to be used.

4.2 Establishing the subject

4.2.1 Using the about attribute

The subject of a triple is usually indicated using the about attribute, as follows:

<link about="mailto:daniel.brickley@bristol.ac.uk" rel="foaf:knows" href="mailto:libby.miller@bristol.ac.uk" />
<link about="mailto:libby.miller@bristol.ac.uk" rel="foaf:knows" href="mailto:ian.sealy@bristol.ac.uk" />
                    

This syntax will usually be used when the statements being made are not pertinent to the document containing them, as shown here:

<blockquote>
    <meta about="urn:isbn:0140449132" property="dc:creator" content="Fyodor Dostoevsky" />
    <p>
        Rodion Romanovitch! My dear friend! If you go on in this way
        you will go mad, I am positive! Drink, pray, if only a few drops!
    </p>
</blockquote>
                    

However, it is possible to use this syntax to refer to parts of the containing document, provided the element being referred to has an attribute of type xml:id. For example, we could once again indicate the source of a quote, using the following syntax:

<html xmlns:dc="http://purl.org/dc/elements/1.1/">
    <head>
        <title>On <em>Crime and Punishment</em></title>
        <link about="#q1" rel="dc:source" href="urn:isbn:0140449132" />
    </head>
    <body>
        <blockquote id="q1">
            <p>
                Rodion Romanovitch! My dear friend! If you go on in this way
                you will go mad, I am positive! Drink, pray, if only a few drops!
            </p>
        </blockquote>
    </body>
</html>
                    

Our triples would be:

<#q1> dc:source <urn:isbn:0140449132> .
                    

4.2.2 Using the attribute nodeID

Although the FOAF [FOAF-PROJECT] example used in the previous section is valid, it is more common to say 'a person knows the person with the email address of ...', than it is to say that 'a resource with the [URI reference] of A knows the resource with a [URI reference] of B'.

The triples generated by our previous example, would be.

<mailto:daniel.brickley@bristol.ac.uk> foaf:knows <mailto:libby.miller@bristol.ac.uk> .
<mailto:libby.miller@bristol.ac.uk> foaf:knows <mailto:ian.sealy@bristol.ac.uk> .
                    

but the following would be more accurate:

_:a foaf:mbox <mailto:daniel.brickley@bristol.ac.uk> .
_:b foaf:mbox <mailto:libby.miller@bristol.ac.uk> .
_:a foaf:knows _:b .
                    

In other words, the 'thing' with an email address of A knows the 'thing' with an email address of B.

A [node] with no [URI reference] is a [blank node], but RDF provides the notion of a [unique anonymous ID] to allow [blank node]s to be distinguished from each other. RDF/A allows the creation of [unique anonymous ID]s either explicitly, using the nodeID attribute, or implicitly, as described in section 4.2.4.4.

The nodeID attribute could be used to mark-up the two [blank node]s in our previous example, as follows:

<link nodeID="a" rel="foaf:mbox" href="mailto:daniel.brickley@bristol.ac.uk" />
<link nodeID="b" rel="foaf:mbox" href="mailto:libby.miller@bristol.ac.uk" />
                    

To refer to the [blank node]s we use an XPointer Framework [XPOINTER-FRAMEWORK] scheme-based pointer of "bnode", as illustrated here:

<link about="#bnode(a)" rel="foaf:knows" href="#bnode(b)" />
                    
The bnode() Scheme Syntax is simply:
[1]   BnodeSchemeData   ::=   (NCName)

An implementation of the bnode() scheme can return a [unique anonymous ID] in any valid format that meets the requirements of [RDF-CONCEPTS]. However, the same processor should always return the same value for the same input. In addition, it is not an error if the parameter does not refer to a value used in a nodeID attribute.

4.2.3 Using an attribute of type xml:id

If an [RDF/A element] does not contain an about attribute, but does contain an attribute of type xml:id then this is used for the subject. With this syntax, the previous example could also be represented as follows:

<html xmlns:dc="http://purl.org/dc/elements/1.1/">
    <head>
        <title>On <em>Crime and Punishment</em></title>
    </head>
    <body>
        <blockquote id="q1" rel="dc:source" href="urn:isbn:0140449132">
            <p>
                Rodion Romanovitch! My dear friend! If you go on in this way
                you will go mad, I am positive! Drink, pray, if only a few drops!
            </p>
        </blockquote>
    </body>
</html>
                    

This generates exactly the same [triple] as before:

<#q1> dc:source <urn:isbn:0140449132> .
                    

4.2.4 Using the [context statement]s subject

If neither an about attribute, nor a nodeID attribute, nor an attribute of type xml:id is present, then the subject of the [context statement] is used. If the [context statement] has a nodeID attribute, this is used first; if it has an about attribute that is used next, and if an attribute of type xml:id is present, that is used. If no explicit subject is present, a [unique anonymous ID] is generated, based on the [context statement].

4.2.4.1 Using the [context statement]'s nodeID attribute

If the [context statement] had its subject set with a nodeID attribute, then that is used for the subject. The following example shows an omitted subject, but since there is a nodeID attribute present on the parent element, this is used as the subject:

<blockquote nodeID="a">
    <link rel="dc:source" href="urn:isbn:0140449132" />
    <p>
        Rodion Romanovitch! My dear friend! If you go on in this way
        you will go mad, I am positive! Drink, pray, if only a few drops!
    </p>
</blockquote>
                        

The triples generated are:

_:a dc:source <urn:isbn:0140449132> .
                        
4.2.4.2 Using the [context statement]'s about attribute

In the following example we have omitted about from line 2, but since the parent element contains an about attribute, that becomes the subject of both the nested statement, and the parent statement:

<link about="http://internet-apps.blogspot.com/" rel="dc:creator" href="http://www.blogger.com/profile/1109404">
    <meta property="dc:title" content="Internet Applications" />
</link>
                        

This is exactly equivalent to making two separate statements, as follows:

<link about="http://internet-apps.blogspot.com/" rel="dc:creator" href="http://www.blogger.com/profile/1109404" />
<meta about="http://internet-apps.blogspot.com/" property="dc:title" content="Internet Applications" />
                        

The triples generated are as follows:

<http://internet-apps.blogspot.com/> dc:creator <http://www.blogger.com/profile/1109404> .
<http://internet-apps.blogspot.com/> dc:title "Internet Applications" .
                        

Note:

This pair of triples could also have been marked-up in this way:

<meta about="http://internet-apps.blogspot.com/" content="Internet Applications">
    <link rel="dc:creator" href="http://www.blogger.com/profile/1109404" />
</meta>
                            

However, this syntax should be used with some caution, since as we shall see later, if the content attribute is omitted then the object is obtained from the mark-up inside the meta element, and the datatype is set to a [typed literal] with a datatype of [XML literal]. This would mean that if the previous example were modified to remove the content attribute, as shown here:

<meta about="http://internet-apps.blogspot.com/">
    <link rel="dc:creator" href="http://www.blogger.com/profile/1109404" />
</meta>
                            

then the mark-up would now only represent one [triple] and not two:

<http://internet-apps.blogspot.com/> dc:title '<link rel="dc:creator" href="http://www.blogger.com/profile/1109404" />'^^rdf:XMLLiteral .
                        
4.2.4.3 Using the [context statement]'s id attribute

It's also possible that the [context statement] had its subject set with an attribute of type xml:id. The following example shows once again an omitted subject, but in this case since there is an attribute of type xml:id present on the [context statement], this is used as the subject:

<blockquote id="q1">
    <link rel="dc:source" href="urn:isbn:0140449132" />
    <p>
        Rodion Romanovitch! My dear friend! If you go on in this way
        you will go mad, I am positive! Drink, pray, if only a few drops!
    </p>
</blockquote>
                        

The triples generated are exactly as with our earlier examples using xml:id:

<#q1> dc:source <urn:isbn:0140449132> .
                        
4.2.4.4 Generating implicit [unique anonymous ID]s

If the [context statement] also has no subject, then the subject is a [unique anonymous ID]. The following example was shown earlier:

<blockquote>
    <link rel="dc:source" href="urn:isbn:0140449132" />
    <p>
        Rodion Romanovitch! My dear friend! If you go on in this way
        you will go mad, I am positive! Drink, pray, if only a few drops!
    </p>
</blockquote>
                        

and generates the following triples:

_:a dc:source <urn:isbn:0140449132> .
                        

Note that the [unique anonymous ID] is generated for the [context statement] and not for the [current statement]. This allows further statements to be made about the same [blank node]. For example:

<blockquote>
    <link rel="dc:source" href="urn:isbn:0140449132" />
    <meta property="dc:creator" content="Fyodor Dostoevsky" />
    <p>
        Rodion Romanovitch! My dear friend! If you go on in this way
        you will go mad, I am positive! Drink, pray, if only a few drops!
    </p>
</blockquote>
                        

would generate these triples:

_:a dc:source <urn:isbn:0140449132> .
_:a dc:creator "Fyodor Dostoevsky" .
                        

and not these:

_:a dc:source <urn:isbn:0140449132> .
_:b dc:creator "Fyodor Dostoevsky" .
                        

However, if the second statement was nested within the first:

<blockquote>
    <link rel="dc:source" href="urn:isbn:0140449132">
        <meta property="dc:creator" content="Fyodor Dostoevsky" />
    </link>
    <p>
        Rodion Romanovitch! My dear friend! If you go on in this way
        you will go mad, I am positive! Drink, pray, if only a few drops!
    </p>
</blockquote>
                        

then we would indeed obtain the following triples:

_:a dc:source <urn:isbn:0140449132> .
_:b dc:creator "Fyodor Dostoevsky" .
                        

4.3 Establishing the predicate

The predicate of a statement is usually specified using a property, rel or rev attribute. These attributes can be placed on any element in a document, and -- although readability may suffer -- can even co-exist on the same element.

4.3.1 Using the property attribute

If the predicate is expressed using the property attribute, then the object of the statement will be a [literal]. The actual value of the [literal] is discussed in a later section. The following example indicates the name of the author responsible for the text being quoted:

<html xmlns:dc="http://purl.org/dc/elements/1.1/">
    <head>
        <title>On <em>Crime and Punishment</em></title>
    </head>
    <body>
        <blockquote property="dc:creator" content="Fyodor Dostoevsky">
            <p>
                Rodion Romanovitch! My dear friend! If you go on in this way
                you will go mad, I am positive! Drink, pray, if only a few drops!
            </p>
        </blockquote>
    </body>
</html>
                

4.3.2 Using the rel attribute

If the predicate is expressed using the rel attribute, then the object of the statement will be a [URI reference]. The actual value of the [URI reference] is discussed in the next section. The following example indicates that one 'FOAF person' knows another:

<link about="mailto:daniel.brickley@bristol.ac.uk" rel="foaf:knows" href="mailto:libby.miller@bristol.ac.uk" />
                    

The triple generated is:

<mailto:daniel.brickley@bristol.ac.uk> foaf:knows <mailto:libby.miller@bristol.ac.uk> .
                    

4.3.3 Using the rev attribute

If the predicate is expressed using the rev attribute, then the three parts of the [triple] generated have the same values as they would have had, had the rel attribute been used, except that the subject and object are reversed. The following example indicates that one 'FOAF person' knows another:

<link about="mailto:daniel.brickley@bristol.ac.uk" rev="foaf:knows" href="mailto:libby.miller@bristol.ac.uk" />
                    

and the [triple] generated is essentially a reversal of our previous example:

<mailto:libby.miller@bristol.ac.uk> foaf:knows <mailto:daniel.brickley@bristol.ac.uk> .
                    

4.3.4 Using the [context statement]'s predicate

If a predicate is not specified for a particular object then the predicate of the statement is determined from the property with the same name in the [context statement]. If there isn't one, then a default predicate of "hasReferenceTo" is used.

4.3.4.1 Using the [context statement]'s predicate

In the following example we have a FOAF person that knows some other people:

<link about="mailto:daniel.brickley@bristol.ac.uk" rel="foaf:knows" href="mailto:libby.miller@bristol.ac.uk">
    <link rel="foaf:knows" href="mailto:ian.sealy@bristol.ac.uk" />
    <link rel="foaf:knows" href="mailto:m.l.poulter@bristol.ac.uk" />
</link>
                        

According to our rules for setting the subject, all of the statements contained by the outer element will have a subject of <mailto:daniel.brickley@bristol.ac.uk>. However, it is also possible to make use of the predicate on the containing element, as follows:

<link about="mailto:daniel.brickley@bristol.ac.uk" rel="foaf:knows" href="mailto:libby.miller@bristol.ac.uk">
    <link href="mailto:ian.sealy@bristol.ac.uk" />
    <link href="mailto:m.l.poulter@bristol.ac.uk" />
</link>
                        

A further refinement would be to place all of the objects inside the container:

<link about="mailto:daniel.brickley@bristol.ac.uk" rel="foaf:knows">
    <link href="mailto:libby.miller@bristol.ac.uk" />
    <link href="mailto:ian.sealy@bristol.ac.uk" />
    <link href="mailto:m.l.poulter@bristol.ac.uk" />
</link>
                        

The triples generated for all of the preceding examples are:

<mailto:daniel.brickley@bristol.ac.uk> foaf:knows <mailto:libby.miller@bristol.ac.uk> .
<mailto:daniel.brickley@bristol.ac.uk> foaf:knows <mailto:ian.sealy@bristol.ac.uk> .
<mailto:daniel.brickley@bristol.ac.uk> foaf:knows <mailto:m.l.poulter@bristol.ac.uk> .
                        

Note:

As can be seen this is an application of two rules, in that we are inheriting both the predicate and subject. Whilst this is the most likely usage, the following permutation is also valid, although may be slightly more difficult for the human reader to decipher:

<!--
    Let's make loads of 'FOAF knows' statements:
-->
<link about="mailto:daniel.brickley@bristol.ac.uk" rel="foaf:knows" rev="foaf:knows" href="mailto:libby.miller@bristol.ac.uk">
    <link about="mailto:libby.miller@bristol.ac.uk" href="mailto:ian.sealy@bristol.ac.uk" />
    <link about="mailto:ian.sealy@bristol.ac.uk" href="mailto:m.l.poulter@bristol.ac.uk" />
    <link href="mailto:ian.sealy@bristol.ac.uk" />
    <link href="mailto:m.l.poulter@bristol.ac.uk" />
</link>
                            

The triples generated are below (note that each element actually generates two triples, since both rel and rev are present):

<mailto:daniel.brickley@bristol.ac.uk> foaf:knows <mailto:libby.miller@bristol.ac.uk> .
<mailto:libby.miller@bristol.ac.uk> foaf:knows <mailto:daniel.brickley@bristol.ac.uk> .

<mailto:libby.miller@bristol.ac.uk> foaf:knows <mailto:ian.sealy@bristol.ac.uk> .
<mailto:ian.sealy@bristol.ac.uk> foaf:knows <mailto:libby.miller@bristol.ac.uk> .

<mailto:ian.sealy@bristol.ac.uk> foaf:knows <mailto:m.l.poulter@bristol.ac.uk> .
<mailto:m.l.poulter@bristol.ac.uk> foaf:knows <mailto:ian.sealy@bristol.ac.uk> .

<mailto:daniel.brickley@bristol.ac.uk> foaf:knows <mailto:ian.sealy@bristol.ac.uk> .
<mailto:ian.sealy@bristol.ac.uk> foaf:knows <mailto:daniel.brickley@bristol.ac.uk> .

<mailto:daniel.brickley@bristol.ac.uk> foaf:knows <mailto:m.l.poulter@bristol.ac.uk> .
<mailto:m.l.poulter@bristol.ac.uk> foaf:knows <mailto:daniel.brickley@bristol.ac.uk> .
                            
4.3.4.2 Using "hasReferenceTo"

If the predicate is omitted, and the [context statement] also has no predicate, then a default value of "hasReferenceTo" is used if the object is a [literal]. The most common usage of this syntax is to indicate that some text in a document actually has a useful value that is different to the actual text. Through this mechanism it is possible to provide normalised values, such as dates, names for countries and people, and so on.

An example may make this clearer. If we have an article that refers to :

Editorial note 
Need to find a few good examples.

Issue (i1):

It feels like we probably need two default properties, one for references to [RDF URI reference]s and one for [literal]s.

Resolution:

None recorded.

4.4 Establishing the object

The object of the statement can be set using one of the attributes content or href. Which attribute is used depends on how the predicate was set. If the predicate was set using property then the object will be a [literal], and its value will come from the content attribute. If the predicate was set with either rel or rev, then the object will be a [URI reference], and its value will come from the href attribute.

4.4.1 Using the content attribute

The content attribute can be used to indicate a [plain literal] as follows:

<meta about="http://internet-apps.blogspot.com/" property="dc:creator" content="Mark Birbeck" />
                    

4.4.2 Using the href attribute

The href attribute can be used to indicate a [URI reference] as follows:

<link about="mailto:daniel.brickley@bristol.ac.uk" rel="foaf:knows" href="mailto:libby.miller@bristol.ac.uk" />
<link about="mailto:daniel.brickley@bristol.ac.uk" rev="foaf:knows" href="mailto:libby.miller@bristol.ac.uk" />
                    

4.4.3 Providing an object to the [context statement]

During the processing of each statement, a check is made on the [context statement] to see if it has a predicate but no object. If it does, then a triple is generated which has the subject and predicate provided by the [context statement], but with the object set to the subject of the statement being evaluated.

For example, given the following mark-up :

<link nodeID="a" rel="foaf:depiction">
    <link about="http://www.ilrt.bristol.ac.uk/people/cmdjb/events/dc7/orig/eric.png">
        <link rel="rdf:type" href="http://xmlns.com/foaf/0.1/Image" />
        <link rel="dc:thumbnail" href="http://www.ilrt.bristol.ac.uk/people/cmdjb/events/dc7/orig/eric.png" />
        <meta property="dc:title" content="Eric Miller, relaxing." />
        <meta property="dc:description" content="Eric Miller, relaxing." />
        <meta property="dc:format" content="image/png" />
    </link>
</link>
                    

a processor would proceed as follows:

  1. The first line does not contain an object, so nothing is generated.

  2. The second line does not contain a predicate or an object, so nothing is generated. However, the [context statement] has no object so a [triple] is generated with the subject and object provided by the [context statement], and the object provided by the subject in the statement being evaluated. The [triple] generated would be:

    _:a foaf:depiction <http://www.ilrt.bristol.ac.uk/people/cmdjb/events/dc7/orig/eric.png> .
                                    
  3. The third line does not contain a subject, so the subject for the [context statement] is used, yielding the following triples:

    <http://www.ilrt.bristol.ac.uk/people/cmdjb/events/dc7/orig/eric.png> rdf:type foaf:Image .
                                    
  4. The remaining lines also do not contain subjects, so in each case the subject for the [context statement] is used, giving the following triples:

    <http://www.ilrt.bristol.ac.uk/people/cmdjb/events/dc7/orig/eric.png> dc:thumbnail <http://www.ilrt.bristol.ac.uk/people/cmdjb/events/dc7/orig/eric.png> .
    <http://www.ilrt.bristol.ac.uk/people/cmdjb/events/dc7/orig/eric.png> dc:title "Eric Miller, relaxing." .
    <http://www.ilrt.bristol.ac.uk/people/cmdjb/events/dc7/orig/eric.png> dc:description "Eric Miller, relaxing." .
    <http://www.ilrt.bristol.ac.uk/people/cmdjb/events/dc7/orig/eric.png> dc:format "image/png" .
                                    

    Note also that although in each case the [context statement] does not contain an object, since it also does not contain a predicate then no further triples are generated.

4.5 Summary

Editorial note 
This section will contain a summary of the syntax.

5 RDF Concepts

Having established the different parts of the syntax of RDF/A, we will now look at the various aspects of the RDF Abstract Syntax, and see how they can be represented in RDF/A.

5.1 Literals as Objects

5.1.1 Plain Literals

When the object of a statement is a [plain literal], then the value of the object is provided by the content attribute. For example, say the author of a blog is represented by the following triples:

<http://internet-apps.blogspot.com/> dc:creator "Mark Birbeck" .
    	

If the blog was marked up using XHTML 1.1, then this triple could be encoded with RDF/A as follows:

<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Internet Applications</title>
        <meta about="http://internet-apps.blogspot.com/" property="dc:creator" content="Mark Birbeck" />
    </head>
    <body>My blog.</body>
</html>
                    
5.1.1.1 Language Tags

RDF allows [plain literal]s to have a language tag, as illustrated by the following example from [RDFTESTS-RDFMS-XMLLANG-TEST006]:

<http://example.org/node> <http://example.org/property> "chat"@fr .
    	         

In RDF/A the XML language attribute -- xml:lang -- is used to add this information:

<meta about="http://example.org/node" property="ex:property" xml:lang="fr" content="chat" />
                       

Note that the value can be inherited as defined in [XML-LANG], so the following syntax will give the same triple as above:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr">
    <head>
        <title xml:lang="en">Example</title>
        <meta about="http://example.org/node" property="ex:property" content="chat" />
    </head>
    ...
</html>
                    

5.1.2 Typed Literals

RDF allows [literal]s to be given a data type, as illustrated by the following example from [RDFTESTS-DATATYPES-TEST001]:

<http://example.org/foo> <http://example.org/bar> "10"^^<http://www.w3.org/2001/XMLSchema#integer> .
                    

This can be represented in RDF/A as follows:

<meta about="http://example.org/foo" property="ex:bar" content="10" datatype="xsd:integer" />
                    
5.1.2.1 XML Literals

XML documents cannot contain XML mark-up in their attributes, which means it is not possible to represent XML within the content attribute. The following would cause an XML parser to generate an error:

<head about="">
    <meta property="dc:creator" content="Albert Einstein" />
    <meta property="dc:title" content="E = mc<sup>2</sup>: The Most Urgent Problem of Our Time" />
</head>
                        

It does not help to escape the content, since the output would simply be a string of text containing numerous ampersands:

<> dc:title "E = mc&lt;sup&gt;2&lt;/sup&gt;: The Most Urgent Problem of Our Time" .
                        

RDF does, however, provide a datatype for indicating [XML literal]s. RDF/A therefore adds this datatype to any [literal] that is indicated using child text nodes on the [RDF/A statement]. For example:

<head about="">
    <meta property="dc:creator" content="Albert Einstein" />
    <meta property="dc:title">E = mc<sup>2</sup>: The Most Urgent Problem of Our Time</meta>
</head>
                        

would generate:

<> dc:creator "Albert Einstein" .
<> dc:title "E = mc<sup>2</sup>: The Most Urgent Problem of Our Time"^^rdf:XMLLiteral .
                        

5.2 Blank nodes

A [blank node] is generated either when the attribute nodeID is present, or when both the [current statement] and the [context statement] have no subject. In the latter case, the [unique anonymous ID] generated to identify the [blank node] is associated with the [context statement], and not the statement currently being evaluated. This allows a number of statements to be made about the same [blank node], as shown in an earlier example, and repeated here:

<blockquote>
    <link rel="dc:source" href="urn:isbn:0140449132" />
    <meta property="dc:creator" content="Fyodor Dostoevsky" />
    <p>
        Rodion Romanovitch! My dear friend! If you go on in this way
        you will go mad, I am positive! Drink, pray, if only a few drops!
    </p>
</blockquote>
                

This would generate the following [triple]s:

_:a dc:source <urn:isbn:0140449132> .
_:a dc:creator "Fyodor Dostoevsky" .
                

To establish relationships between [blank node]s the [unique anonymous ID] must be either set explicity using the nodeID attribute, or the statements must be nested. statements. For example, if our desired output is the following [triple]s:

_:a foaf:mbox mailto:daniel.brickley@bristol.ac.uk .
_:b foaf:mbox mailto:libby.miller@bristol.ac.uk .
_:a foaf:knows _:b .
                

we could either use explicit [unique anonymous ID]s:

<link nodeID="a" rel="foaf:mbox" href="mailto:daniel.brickley@bristol.ac.uk" />
<link nodeID="b" rel="foaf:mbox" href="mailto:libby.miller@bristol.ac.uk" />
<link about="#bnode(a)" rel="foaf:knows" href="#bnode(b)" />
                

or implicit [unique anonymous ID]s, by nesting the statements:

<link rel="foaf:mbox" href="mailto:daniel.brickley@bristol.ac.uk">
    <link rel="foaf:knows">
        <link rel="foaf:mbox" href="mailto:libby.miller@bristol.ac.uk" />
    </link>
</link>
                

The processing steps for the implicit approach, are:

  1. The first line has no explicit subject, so a triple with a [unique anonymous ID] for the subject, is generated:

    _:a foaf:mbox mailto:daniel.brickley@bristol.ac.uk .
                            
  2. The second line has no subject, but since it also has no object, nothing is generated.

  3. The third line has no explicit subject, so a triple with a [unique anonymous ID] for the subject, is generated:

    _:b foaf:mbox mailto:libby.miller@bristol.ac.uk .
                            
  4. Whilst processing the third line, a check is also made for on the [context statement] for a predicate with no object. Since this is the case, a triple is generated with the subject and predicate from the [context statement] and with the object set to the value of the subject from the [current statement]. Note that the subject of the second line is evaluated in the usual way, and so is actually the subject of the first line, which in this case is the first [unique anonymous ID]:

    _:a foaf:knows _:b .
                            

6 Examples

6.1 Creative Commons

One of the advantages of using the same syntax to make general statements as well as statements about a document is that in many cases a document can carry its own metadata. For example, if an XHTML document contains a navigable link to the Creative Commons license, this link can also be used to express metadata:

<p>
    This document is licensed under a
    <a rel="cc:license" href="http://creativecommons.org/licenses/by-sa/2.0/">
        Creative Commons License
    </a>
    which, among other things, requires that you provide 
    attribution to the author,
    <a rel="dc:creator" href="http://ben.adida.net">Ben Adida</a>.
</p>
                

The statements are not, however, about the document -- the two anchors in this example will generate two unique [anonymous node]s:

_:a cc:license <http://creativecommons.org/licenses/by-sa/2.0/>
_:b dc:creator <http://ben.adida.net>
                

7 Rules

Editorial note 
The following is now slightly out of sync with the text above.
Editorial note 
The following will be converted to a GRDDL format.
<!--
    CS is the [current statement], and CTX is the [context statement]
-->
<!--
    A function for establishing the subject given an element
-->
function subj(e)
{
    var s = null;
    var p = e.parent;

    if (e.about)
        s = e.about;
    else if (e.nodeID)
        s = "_:" + e.nodeID;
    else if (e.id)
        s = base + "#" + e.id;
    else if (p.about)
        s = p.about;
    else if (p.nodeID)
        s = "_:" + p.nodeID;
    else if (p.id)
        s = base + "#" + p.id;
    return s;
}

<!--
    Establish the subject of this statement
-->
s = subj(CS);

<!--
    If we failed to establish a subject generate a bnode
    based on CTX. Also set the 'target' for CTX, if it needs it
-->
if (s)
    t = s;
else
{
    s = generated-blank-node-id(CTX);
    t = generated-blank-node-id(CS);
}

<!--
    If CTX has @rel or @rev, with no @href, then use the
    'target' set above to 'fill in the gaps'.
-->
sctx = subj(CTX);
if (!sctx)
    sctx = generated-blank-node-id(CTX.parent);

if (CTX.rel AND !CTX.href)
    generate-triple(sctx, CTX.rel, t), 

if (CTX.rev AND !CTX.href)
    generate-triple(sctx, CTX.rev, t), 

<!--
    Now we can generate triples for CS
-->
if (CS.href)
{
    o = CS.href;

    if (CS.rel OR CS.rev)
    {
        p1 = CS.rel;
        p2 = CS.rev;
    }
    else
    {
        if (CTX.rel OR CTX.rev)
        {
            p1 = CTX.rel;
            p2 = CTX.rev;
        }
    }

    if (s && p1 && o)
        generate-triple(s, p1, o);

    if (s && p2 && o)
        generate-triple(o, p2, s);
}

if (CS.content)
{
    p = null;
    o = CS.content;

    if (CS.property)
        p = CS.property;
    else
    {
        if (CTX.property)
            p = CTX.property;
    }

    if (s && p && o)
        generate-triple(s, p, o);
}
            

8 Bibliography

DC
Dublin Core Metadata Initiative (DCMI) (See http://dublincore.org/.)
FOAF-PROJECT
The FOAF Project (See http://www.foaf-project.org.)
HTML
HTML 4.01 Specification (See http://www.w3.org/TR/html401/.)
N-TRIPLES
RDF Test Cases, N-Triples (See http://www.w3.org/TR/rdf-testcases/#ntriples.)
N3-PRIMER
N3 Primer (See http://www.w3.org/2000/10/swap/Primer.)
RDF-CONCEPTS
Resource Description Framework (RDF): Concepts and Abstract Syntax (See http://www.w3.org/TR/rdf-concepts/.)
RDF-SYNTAX
RDF/XML Syntax and Grammar (See http://www.w3.org/TR/rdf-syntax-grammar/.)
RDFTESTS-DATATYPES-TEST001
datatypes/test001.nt (See http://www.w3.org/2000/10/rdf-tests/rdfcore/datatypes/test001.nt.)
RDFTESTS-RDFMS-XMLLANG-TEST006
rdfms-xmllang/test006.nt (See http://www.w3.org/2000/10/rdf-tests/rdfcore/rdfms-xmllang/test006.nt.)
RELAXNG
RELAX NG Home Page (See http://www.relaxng.org/.)
XHTML
XHTML 1.0 (See http://www.w3.org/TR/xhtml1.)
XHTML-2.0-LINKTYPES
XHTML 2.0 Link Types (See http://www.w3.org/MarkUp/Group/2003/WD-xhtml2-20031029/abstraction.html#dt_LinkTypes.)
XML-BASE
XML Base (See http://www.w3.org/TR/xmlbase/.)
XML-LANG
Extensible Markup Language (XML) 1.0 (Third Edition), Language Identification (See http://www.w3.org/TR/REC-xml/#sec-lang-tag.)
XPOINTER-FRAMEWORK
XPointer Framework (See http://www.w3.org/TR/xptr-framework/.)