Archive for the ‘RDFa’ Category

Drupal7 RDFa XMLLiteral content processing

Saturday, March 12th, 2011

Drupal 7 supports RDFa 1.0 as part of the core product. RDFa 1.0 is the current specification but RDFa 1.1 is to be released shortly.

RDFa 1.0 metadata can be parsed using the RDFa Distiller and Parser while the RDFa Distiller and Parser (Test Version for RDFa 1.1) can be used to extract RDFa 1.1.

Creating a simple Drupal 7 test blog and parsing out the RDFa 1.0 metadata with the RDFa Distiller and Parser shows that Drupal 7 is using the SIOC (Semantically-Interlinked Online Communities) ontology to describe blog posts and identifies the Drupal user as the creator of the post using the sioc:has_creator property.

<sioc:Post rdf:about="http://137breakerbay.3kbo.com/test">
  <rdf:type rdf:resource="http://rdfs.org/sioc/types#BlogPost"/>
  ...
  <sioc:has_creator>
    <sioc:UserAccount rdf:about="http://137breakerbay.3kbo.com/user/2">
      <foaf:name>Richard</foaf:name>
    </sioc:UserAccount>
  </sioc:has_creator>
  ...
  <content:encoded rdf:parseType="Literal"><p xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">Test Blog</p>
  </content:encoded>
</sioc:Post>

The sioc:UserAccount is a sub class of foaf:OnlineAccount.

What I would like to do is add additional RDFa metadata within the content of the blog to associate me, the Drupal 7 user with a sioc:UserAccount, to me the foaf:Person identified by my FOAF file.

Drupal 7 content is wrapped by XHTML elements containing the property=”content:encoded” (shown below) and an RDFa parser treats this content as an XMLLiteral.

<div property="content:encoded">
...
</div>

The problem is that RDFa 1.0 parsers don’t extract metadata contained within the XMLLiteral.

This was raised in the issue “XMLLiteral content isn’t processed for RDFa attributes in RDFa 1.0 – should this change in RDFa 1.1? a while back with the result that in RDFa 1.1 parsers should now also process the XMLLiteral content.

To make sure that the RDFa parsers know that I want to use RDFa 1.1 processing I need to update Drupal 7 to use the  XHTML+RDFa Driver Module defined in the XHTML+RDFa 1.1 spec.

This turns out to be a simple update of one Drupal 7 file, site/modules/system/html.tpl.php.

Near the top of the file the version is changed to 1.1 (in two places) and the dtd changed to  “http://www.w3.org/MarkUp/DTD/xhtml-rdfa-2.dtd”.

?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.1//EN"
  "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-2.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php print $language->language; ?>" version="XHTML+RDFa 1.1" dir="<?php print $language->dir; ?>"<?php print $rdf_namespaces; ?>>

With these changes made I can create another blog containing the following RDFa metadata

<div about="http://www.3kbo.com/people/richard.hancock/foaf.rdf#i" typeof="foaf:Person">
<div rel="foaf:account" resource="http://137breakerbay.3kbo.com/user/2">
...
<div>
</div>

knowing that that an RDFa 1.1 parser will create the RDF triples below which link the Drupal 7 user to me the person identified in my FOAF file.

  <foaf:Person rdf:about="http://www.3kbo.com/people/richard.hancock/foaf.rdf#i">
    <foaf:account>
      <sioc:UserAccount rdf:about="http://137breakerbay.3kbo.com/user/2">
        <foaf:name>Richard</foaf:name>
      </sioc:UserAccount>
    </foaf:account>
  </foaf:Person>

The differences between the RDF extracted with an RDFa 1.0 parser and an RDFa 1.1 parser can be seen using the two links below.

Now that I know that the RDFa 1.1 metadata embedded in the content will be processed accordingly I can move on to the task of building 137 Breaker Bay, a simple accommodation site where the plan is to use RDFa and ontologies such as GoodRelations to describe the both the accommodation services available and the attractions and services of the surrounding area.

A Simple HTML5 RDFa Example

Wednesday, November 10th, 2010

As part of learning HTML5 and RDFa I put together a Simple HTML5 RDFa Example, using a photo Irene took of Minoan Figurines during a trip to Crete for the main content.

A Simple HTML5 RDFa Example

Identifying Things

Using RDFa I wanted to generate RDF statements about:

Each of these five things requires an URI. The example automatically has one ( http://www.3kbo.com/examples/rdfa/simple.html ) while Irene and myself are identified by our FOAF files, Irene and Richard.

The remaining two URIs are created by adding the HTML bookmarks “crete” and “minoan-figurines” to the example, generating the URIs:

HTML5 Doctype and RDFa Version

To support both HTML5 and RDFa I added the following html5 doctype and rdfa version declaration.

<!DOCTYPE html>
<html version="HTML+RDFa 1.1" lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:foaf="http://xmlns.com/foaf/0.1/">

The HTML5 new elements header, hgroup, nav, section, article and footer are used in the example, primarily for constructing a document structure that will be developed further in the future.

Viewing the RDF

The  link RDF extracted by pyRDFa uses the RDFa Distiller and Parser to extract the RDF statements. If Tabulator is installed clicking the link provides the following view of the generated RDF.

A Simple HTML5 RDFa Extraction

About the Example

The statements about A Simple HTML5 RDFa Example are all made in the document meta data, using the properties dc:date, dc:created, dc:creator, dc:title and dc:subject from the Dublin Core Metadata Element Set. The metadata in the head of the document refers to the example itself.

<head profile="http://www.w3.org/1999/xhtml/vocab">
<meta property="dc:date dc:created" content="2010-11-11T13:00:00" />
<meta rel="dc:creator" 	href="http://www.3kbo.com/people/richard.hancock/foaf.rdf#i" />
<meta rel="dc:subject" href="http://dbpedia.org/resource/Semantic_Web" />
<meta rel="dc:subject" href="http://dbpedia.org/resource/RDFa" />
<meta rel="dc:subject" href="http://dbpedia.org/resource/HTML5" />
<meta rel="dc:subject" href="http://dbpedia.org/resource/SPARQL" />
<meta rel="dc:subject" 	href="http://dbpedia.org/resource/Crete" />
<meta rel="dc:subject" 	href="http://dbpedia.org/resource/Minoan_civilization" />
<title property="dc:title">A Simple HTML5 RDFa Example</title>
...
</head>

About Crete and the Minoan Figurines

In the code below the RDFa about attribute, specified as about=”#crete” and about=”#minoan-figurines”, sets the current subject for the article on Crete and the photo of the Minoan Figurines respectively.  The appropriate creator and subject is also assigned to each subject.

<a name="crete" />
<div about="#crete" rel="dc:creator" href="http://www.3kbo.com/people/richard.hancock/foaf.rdf#i">
<h2 about="#crete" rel="dc:subject" href="http://dbpedia.org/resource/Crete" property="dc:title">Crete 2010</h2>
<a name="minoan-figurines" />
<div class="imgbox" about="#minoan-figurines"><img 	src="images/minoan-figurines.jpg" alt="figurines" />
<div><span property="dc:title" rel="dc:subject" href="http://dbpedia.org/resource/Minoan_civilization">Minoan Figurines, Crete</span>
photo by <span rel="dc:creator" href="http://www.3kbo.com/people/irene.bell-hancock/foaf.rdf#me">Irene</span>.</div>
</div>
</div>

About Richard and Irene

For Richard and Irene the typeof attribute is set to foaf:Person,  the about attribute specifies the appropriate FOAF file and foaf:knows is used to specify that Richard knows Irene.

<div class="socialnet" about="http://www.3kbo.com/people/richard.hancock/foaf.rdf#i" typeof="foaf:Person" property="foaf:name" content="Richard Hancock">
<p><span property="foaf:firstname">Richard</span> knows</p>
<ul rel="foaf:knows">
<li typeof="foaf:Person" about="http://www.3kbo.com/people/irene.bell-hancock/foaf.rdf#me">
	<a property="foaf:name" rel="foaf:homepage" href="http://picasaweb.google.com/goannagraphics">Irene</a></li>
</ul>
</div>

Combining Information

One of the benefits of using RDF is that it easy to combine information. A small example of how easily RDF statements from different sources can be combined is provided using Tabulator. If the link RDF extracted by pyRDFa is opened in Tabulator followed by the link to Irenes FOAF file then the is creator of statement is included in the second Tabulator view, even though it is not present in the original FOAF file.

A Simple HTML5 RDFa Example Irene

Because Irene is uniquely identified Tabulator can safely combine the information from the two datasources.

SPARQL Query for Content By Author

RDF extracted from the example can be queried using SPARQL. The following query identifying the content authors can be pasted into the sparql.org query form. The FROM key word specifies that the query will use the RDF extracted from the example, yielding the following results.

PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
select ?Content ?Author
FROM <http://www.w3.org/2007/08/pyRdfa/extract?uri=http://www.3kbo.com/examples/rdfa/simple.html>
where { ?s dc:creator ?o .
?s dc:title ?Content .
?o foaf:name ?Author .
}
order by ?Content

SPARQL Query Results for Content By Author

-----------------------------------------------------------
| Content                          | Author               |
===========================================================
| "A Simple HTML5 RDFa Example"@en | "Richard Hancock"@en |
| "Crete 2010"@en                  | "Richard Hancock"@en |
| "Minonan Figurines, Crete"@en    | "Irene"@en           |
-----------------------------------------------------------

Embedded SPARQL Query

The example contains the SPARQL Query for Content by Author embedded as the link

This URL encodes the SPARQL Query that is sent to the www.sparql.org SPARQL end point.

When the link is selected the SPARQL Query is run against the RDF extracted from the example and returned directly to the browser.

What Next

Both HTML5 and RDFa are addictive. For HTML5 there are lots of new features to explore and for RDFa more meta data to connect up.