UserPreferences

FoafInBrief


Overview

The [WWW]FOAF (Friend of a Friend) project is about creating a Web of machine-readable homepages describing people, the links between them and the things they create and do.

FOAF is an application of [WWW]RDF (Resource Description Framework). It uses a [WWW]vocabulary defined using RDF Schema and [WWW]OWL (Web Ontology Language). The vocabulary is used to describe individual people, usually in the form of a Personal Profile Document on the web, in RDF/XML syntax. These documents may be handwritten or (more commonly) machine-generated - e.g. Live Journal generates one for each of its users.

For a more detailed background on FOAF see [WWW]An Introduction to FOAF

See also:

DanBrickley's [WWW]post to atom-syntax

HenryStory's [WWW]Atom+FOAF Blog

[WWW]Atom+OWL

Describing Resources with RDF

RDF can be seen as a kind of entity/relationship data model designed for the web. This is commonly visualised as a node and arc graph, with nodes representing the entities and arcs representing the relationships between entities.

There are three different kinds of nodes: resources identified with a URI; blank nodes, which act as stand-ins for resources to help build structures; literals, which can provide literal data such as text strings.

The relationships are called properties or predicates. They describe the relationship between two nodes. The nodes and arcs of a graph can be expressed as a series of logical statements (also known as triples), each having three parts: subject, predicate and object.

The exchange syntax for RDF is RDF/XML (there are several other syntaxes).

Here is a cut-down bit of RSS 1.0, which uses RDF/XML:

<rdf:RDF 
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns="http://purl.org/rss/1.0/">

<item rdf:about="http://example.org">
   <title>Something</title>
</item>

</rdf:RDF>

This is another representation of the exact same information (generated using the [WWW]RDF Validator, select Triples and Graph) :

http://dannyayers.com/2004/09/rdf1.png

The statements (triples) here are:

http://example.org rdf:type rss:item

http://example.org rss:title "Something"

The subject of both statements is the identified resource. The predicates are rdf:type and rss:title. The objects are rss:item and the literal "Something".

The definitions of the terms in an RDF vocabulary is also done using RDF, in an RDF Schema. This is rather like class definitions in an Object-Oriented language. They provide machine-readable information about the terms which can be applied to instance data.

See also : [WWW]RDF Primer

Describing People with FOAF

Here is a bit of a FOAF profile:

<rdf:RDF 
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns="http://xmlns.com/foaf/0.1/">

<Person>
  <name>Dan Brickley</name>
  <mbox_sha1sum>241021fb0e6289f92815fc210f9e9137262c252e</mbox_sha1sum>
  <homepage rdf:resource="http://rdfweb.org/people/danbri/" />
  <img rdf:resource="http://rdfweb.org/people/danbri/mugshot/danbri-small.jpeg" />
</Person>
  
</rdf:RDF>

http://dannyayers.com/2004/09/rdf2.png

The <Person> element in the XML is interpreted as a blank node of type foaf:Person, - it doesn't have a URI, but the tool that produced the image (the [WWW]RDF Validator) has labelled it genid:. This is just a locally unique id generated by the validator, it has no significance outside of this image. The person is identified by their characteristics. Some of these characteristics map to a single, unique person and are known as Inverse Functional Properties. <mbox_sha1sum> is one of these, its value being a hashed version of the person's email address. See also : [WWW]Identifying things in FOAF

FOAF and Syndication

Because both RSS 1.0 and FOAF are RDF vocabularies, they may be used together. The definition of RDF/XML is such that mixing of namespace-qualified material is possible, and what's more has an unambiguous interpretation in the RDF model.

Here's an example:

<rdf:RDF 
  xmlns="http://purl.org/rss/1.0/"
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:foaf="http://xmlns.com/foaf/0.1/">

<item rdf:about="http://example.org">
   <title>Something</title>
   <foaf:maker>
      <foaf:Person>
        <foaf:name>Dan Brickley</foaf:name>
        <foaf:homepage rdf:resource="http://rdfweb.org/people/danbri/" />
      </foaf:Person>
   </foaf:maker>
</item>

</rdf:RDF>

http://dannyayers.com/2004/09/rdf3.png

(Try it in the [WWW]RDF Validator)

See also: [WWW]FOAF Output plugin for WordPress

Structural Comparison with Atom Person Construct

At present the Atom person constructs look like this:

<something>
   <title>Example Feed</title>
   <author>
      <name>John Doe</name>
   </author>
</something>

You may note there's a difference in the level of nesting with this FOAFish equivalent:

<something>
   <title>Example Feed</title>
   <maker>
      <Person>
         <name>John Doe</name>
      </Person>
   </maker>
</something>

However, the FOAFish version could be expressed in a way that has nesting like that of Atom :

<something>
   <title>Example Feed</title>
   <maker rdf:parseType="Resource">
         <name>John Doe</name>
   </maker>
</something>

which produces a graph like this:

http://dannyayers.com/2004/09/rdf4.png

In itself, this is lacking the information that the blank node genid:ARP357228 is of type foaf:Person. However, in the RDF Schema for FOAF there is the following:

<rdf:Property rdf:about="http://xmlns.com/foaf/0.1/maker" 
       vs:term_status="testing" 
       rdfs:label="maker" 
       rdfs:comment="An agent that made this thing.">
   <rdfs:domain rdf:resource="http://www.w3.org/2000/01/rdf-schema#Resource"/>
   <rdfs:range rdf:resource="http://xmlns.com/foaf/0.1/Agent"/>
   <rdfs:isDefinedBy rdf:resource="http://xmlns.com/foaf/0.1/"/>
   <owl:inverseOf rdf:resource="http://xmlns.com/foaf/0.1/made"/>
</rdf:Property>

The rdfs:range of foaf:maker is defined as foaf:Agent, which means an RDF application could infer:

[genid:ARP357228] rdf:type foaf:Agent

This would be equivalent to:

<something>
   <title>Example Feed</title>
   <maker>
      <Agent>
         <name>John Doe</name>
      </Agent>
   </maker>
</something>

Not identical, but very close (Person is a subclass of Agent). The technique essentially works.

It seems reasonable to say that the structure of the syntax is probably unimportant in this case, it shouldn't interfere with a direct mapping between Atom and FOAF.