[This local archive copy mirrored from the canonical site: http://www.ccil.org/~cowan/XML/RDF-made-easy.html, 1998-08-19; links may not have complete integrity, so use the canonical document at this URL if possible.]

RDF Made Easy

Disclaimer

This document reflects the W3C Working Draft Resource Description Framework (RDF) Model and Syntax: W3C Working Draft 20 July 1998. You should check the above URL; if it refers to some other Draft, then ignore this document or read it with a grain of salt.

This draft is much improved over earlier drafts, and this document isn't as useful as it once was. But I have corrected it just in case anyone is relying on it.

Introduction

Let me now explain what this document is for. It isn't intended to replace either Tim's high-level explanation, or the detailed formalism of the draft. Instead, it attempts to explain RDF from the simple cases to the general cases rather than the other way around. After reading this document, you should know how to encode Properties in XML in a way that complies with RDF.

I'm assuming that you have a fair understanding of XML 1.0, and I won't spend any time explaining element types, elements, empty elements, attributes, or attribute values.

I also don't want to go into too much detail explaining namespaces, so just let me note one point here. I will be prefixing all RDF elements with RDF:. However, I won't be using RDF: on attributes, because it's assumed that attributes belong to the same namespace as their elements unless explicitly specified otherwise. So HREF means the same as RDF:HREF.

In your documents you can use whatever prefix you want (ending in a colon) as long as you insert a proper namespace declaration. The exact content of that namespace declaration hasn't been defined yet by the draft.

The Simplest RDF

Suppose you want to write some RDF giving a few Properties of a single Resource (remember that a Resource is anything you can locate with an URL or its persistent cousin, an URN). To be concrete, let's say you want to record some facts about this very document, whose URL is http://www.ccil.org/~cowan/XML/RDF-made-easy.html. The author of the document is John Cowan, and the title of the document is "RDF Made Easy". Here's one way of doing it:

    <RDF:RDF>
        <RDF:Description about="http://www.ccil.org/~cowan/XML/RDF-made-easy.html">
            <XX:Author>John Cowan</XX:Author>
            <XX:Title>RDF Made Easy</XX:Title>
        </RDF:Description>
    </RDF:RDF>

In other words, the PropertyTypes and Values are in sub-elements of the RDF:Description element, as element names and #PCDATA content respectively. The Resource is specified by the about attribute of the RDF:Description.

What's the XX:prefix all about? Well, we want to be able to distinguish between your use of Author and Title and other people's uses of the same names. So we suppose that your names are listed in a namespace somewhere, and that the prefix used for that namespace within this document is XX. Of course, you can use any prefix you like as long as you are consistent within a given document.

That's really all there is to it! You can have as many RDF:Description elements within a single RDF:RDF element as you want, and as many sub-elements within an RDF:Description element as you want, so you can describe lots of Properties of lots of Resources within one RDF document.

As a fairly minor convenience, you can use attributes of the RDF:Description element instead of child elements. So an equivalent form of the above example is:

    <RDF:RDF>
        <RDF:Description about="http://www.ccil.org/~cowan/XML/RDF-made-easy.html"
            XX:Author="John Cowan"
            XX:Title="RDF Made Easy"/>
    </RDF:RDF>

Here the RDF:Description element is empty, and has two extra properties XX:Author and XX:Title that give the PropertyTypes (as attribute names) and the Values (as attribute values) of the Properties.

You can't use the attribute names about, ID, or bagID in this way, for reasons that will appear later.

Resources As Values

Suppose you want the Value of a Property to be a Resource. You don't just put the URI of the Resource into the content of the child element that specifies the Property. Instead, you have to give that child element an resource attribute.

Let's suppose you want to give the Home-Page of this document. You can write more RDF:

    <RDF:RDF>
        <RDF:Description about="http://www.ccil.org/~cowan/XML/RDF-made-easy.html">
            <XX:Home-Page resource="http://www.ccil.org/~cowan"/>
        </RDF:Description>
    </RDF:RDF>

That tells you that the Home-Page of this document is http://www.ccil.org/~cowan. Note that since the child XX:Home-Page element has a resource attribute, it mustn't also have #PCDATA content.

This method won't work with Properties specified as attributes. A Property specified as an attribute always has a simple #PCDATA Value.

Collections

RDF provides a mechanism for creating collections, which are special kinds of Resources. A collection doesn't have to have its own URI, although it can. RDF supports three kinds of collections, bags, sequences, and alternatives, represented by RDF:Bag, RDF:Alt, and RDF:Seq elements respectively.

A bag is just a bunch of Values, either simple strings or Resources. To create a bag, use an RDF:Bag element containing RDF:LI elements. Here is a simple bag of color names:

    <RDF:RDF>
        <RDF:Bag>
           <RDF:LI>red</RDF:LI>
           <RDF:LI>green</RDF:LI>
           <RDF:LI>blue</RDF:LI>
        </RDF:Bag>
    </RDF:RDF>

And here's a bag of Resources:

    <RDF:RDF>
        <RDF:Bag>
           <RDF:LI resource="http://www.xml.com/xml/pub/98/06/rdf.html"/>
           <RDF:LI resource="http://www.ccil.org/~cowan"/>
           <RDF:LI resource="http://www.w3.org/TR/WD-xml-names"/>
        </RDF:Bag>
    </RDF:RDF>

Note that RDF:LI elements use the same convention as property elements: either #PCDATA content for a simple string, or a resource attribute for a Resource. A bag can have a mixture of strings and Resources.

Sequences and alternatives are formally just like bags, except that order matters. In a sequence, the components are in the given order (bags have no order); in an alternative, the first RDF:LI element represents the default value of the collection and the other RDF:LI elements represent other possibilities.

How can you use a collection? A typical way to use it is as the immediate Value of a Property. You do this by placing the collection right inside a property element. Here's an example, where the Author of a paper is specified using a sequence. (Why not a bag? The order of authors on a paper is often important, that's why.):

    <RDF:RDF>
        <RDF:Description RDF:HREF="http://www.w3.org/TR/WD-rdf-syntax">
            <XX:Author>
                <RDF:Seq>
                    <RDF:LI>Tim Bray</RDF:LI>
                    <RDF:LI>Jean Paoli</RDF:LI>
                    <RDF:LI>C. M. Sperberg-McQueen</RDF:LI>
                <RDF:Seq>
            </XX:Author>
        </RDF:Description>
    </RDF:RDF>

In general, whenever a property element like XX:Author has neither #PCDATA content nor empty content, then its content must be some kind of RDF element, usually a collection.

If you don't want to put the collection directly into a property element, you can make it a child of an RDF:RDF element and give it an ID property. That gives the collection an actual URI, namely the URL of the document that contains it followed by #id where "id" is the value of the ID element, like this:

    <RDF:RDF>
        <RDF:Description HREF="http://www.w3.org/TR/WD-rdf-syntax">
            <XX:Author HREF="#XMLAuthors"/>
        </RDF:Description>
        <RDF:Seq ID="XMLAuthors">
            <RDF:LI>Tim Bray</RDF:LI>
            <RDF:LI>Jean Paoli</RDF:LI>
            <RDF:LI>C. M. Sperberg-McQueen</RDF:LI>
        <RDF:Seq>
    </RDF:RDF>

In this case, the HREF attribute on the XX:Author element refers to the current document (implicitly), and specifically the part of it defined by ID="XMLAuthors".

Of course, nothing says that the collection and the description have to be inside the same RDF:RDF element, or even in the same XML document. Nothing stops you from putting an ID attribute on a collection embedded inside a description, either.

Descriptions As Resources

An RDF:Description element can be considered as a Resource. In order to give it a name, we just use an ID attribute, just as we do for a collection.

A particularly interesting case is an RDF:Description with an ID attribute but no HREF attribute. In that case, the Resource described by the Properties in the description is the very RDF:Description element itself! Here's an example:

    <RDF:RDF>
        <RDF:Description ID="SelfDateable">
            <XX:Date>1998-06-18</XX:Date>
        </RDF:Description>
    </RDF:RDF>

This says that the Resource named "http://www.ccil.org/~cowan/XML/RDF-made-easy.html#SelfDateable" has an XX:Date property of "1998-06-18".

Collections As Descriptions And Vice Versa

So now we have descriptions and collections, which are different but both useful. Well, it turns out that collections can be viewed as an alternate notation for descriptions, and descriptions can be viewed as collections!

How do we do that? Well, every collection with n elements can be viewed as composed of n+1 properties. Let's take the XMLAuthors sequence above, and describe it using RDF:Description elements. We get the following:

    <RDF:RDF>
        <RDF:Description
                RDF:HREF="http://www.ccil.org/~cowan/XML/RDF-made-easy.html#XMLAuthors">
            <RDF:InstanceOf RDF:HREF="http://www.w3.org/RDF/RDF/Seq"/>
            <RDF:1>Tim Bray</RDF:1>
            <RDF:2>Jean Paoli</RDF:2>
            <RDF:3>C. M. Sperberg-McQueen</RDF:3>
        </RDF:Description>
    </RDF:RDF>

In other words, the XMLAuthors sequence is a Resource with four associated Properties. One uses the PropertyType RDF:InstanceOf and a Value that is a URI for RDF:Seq. (This is a bogus URI; I can't show the actual URI here because the draft hasn't standardized it yet.) The remaining Properties have PropertyTypes RDF:1, RDF:2, and RDF:3, and Values corresponding to the contents of the sequence.

Similarly, a description can be considered as a bag; a bag containing Properties. This bag is named using a bagID property on the description.