RDF Templates Draft 1

This is something I've been ruminating on for a few weeks and finally found time to write up: RDF Templates.

The idea comes from a simple desire: what if there was a way to apply XSLT to an RDF document to produce an (X)HTML page? You can't do it in the general case because there are many, many ways to serialize an RDF graph and not all of them provide the nice tree structure that XSLT requires to operate.

So, I started thinking about how you could have an analog of XSLT that worked with RDF graphs. RDF Templates is what I came up with. It consists of a pattern language which works like XPath and a set of elements that work like XSLT.

It took me a long time to come up with a consistent mental model of what the templates should be doing to the graph but I think I've managed to create something that in that spot between being easy to use and complex to learn. This is a very very early draft of the spec and I'm looking for feedback. I'm also writing a Perl implementation to try out the ideas and I'm looking to share notes with anyone who wants to build implementations in other languages.

RDF Template Language 1.0

This version:
http://blog.iandavis.com/2003/01/rdfTemplatesDraft1.html
Latest version:
http://blog.iandavis.com/2003/01/rdfTemplatesDraft1.html
Previous versions:
None
Author:
Ian Davis <iand@blog.iandavis.com>
Status:
Very early draft; for community review and feedback; major revisions expected; not feature complete

Table of Contents

Introduction

RDF Templates work in a similar fashion to XSLT. However, instead of acting upon an XML document, an RDF Template acts on an RDF graph.

Processing Model

A transformation expressed in RDFT describes rules for creating a result tree from an RDF graph. This is achieved by associating patterns with templates. A pattern is matched against nodes and arcs in the source graph.

An RDF Template Document consists of a set of template rules. Each template rule has two parts: a pattern which is matched against the source graph and a template which can be instantiated to form part of the result tree.

A template is instantiated for a particular source graph to create part of the result tree. A template can contain elements that specify literal result element structure. A template can also contain elements from the RDFT namespace that are instructions for creating result tree fragments. When a template is instantiated, each instruction is executed and replaced by the result tree fragment that it creates. Instructions can select and process sub-graphs of the source graph. Processing a sub-graph creates a result tree fragment by finding the applicable template rule and instantiating its template.

Note that graphs are only processed when they have been selected by the execution of an instruction. The result tree is constructed by finding the template rule for the source graoh and instantiating its template.

In the process of finding the applicable template rule, more than one template rule may have a pattern that matches a given sub-graph. However, only one template rule will be applied. The method for deciding which template rule to apply is described later in this document.

When a template is instantiated, it is always instantiated with respect to a current node and a context graph. The current node is always a member of the context graph.

Template Priorities

TODO: need to determine selection priorities where two or more template rules match for a given graph

Default Templates

TODO: a discussion of default templates and how the whole match process gets kicked off

Patterns

As in XSLT, template rules identify the nodes to which they apply by using a pattern. A pattern specifies a set of conditions on a node or an arc.

There are three types of patterns:

  1. Node selection pattern
  2. Arc selection pattern
  3. Node match pattern

Node Selection Patterns

A node selection pattern specifies a set of criteria that are used to build a list of matching sub-graphs.

The pattern is evaluated against the context graph and any matching nodes are identified. Each matching node forms the basis of a new sub-graph. The following process is followed for each matching node:

  1. A new sub-graph is created
  2. All triples with the matching node as its subject is added to the sub-graph.
  3. All triples with any of the sub-graph's nodes as their subject are added to the sub-graph.
  4. Repeat step three until all triples in the context-graph that have a subject of any node in the sub-graph have been added to the sub-graph.
  5. Add the sub-graph to the list of matching sub-graphs along with a reference to the matching node.

Node Selection Pattern Examples

*
Selects all nodes in the context graph.
uriref('http://blog.iandavis.com/')
Selects all nodes with the given uriref.
type(uriref('http://purl.org/rss/1.0/channel'))
Selects all nodes that have an arc labelled rdf:type with value <http://purl.org/rss/1.0/channel>.
class()
Selects all nodes that have an arc labelled rdf:type with value <http://www.w3.org/2000/01/rdf-schema#Class>.
property()
Selects all nodes that have an arc labelled rdf:type with value <http://www.w3.org/2000/01/rdf-schema#Property>
subClassOf(uriref('http://purl.org/rss/1.0/channel'))
Selects all nodes that have an arc labelled rdfs:subClassOf with value <http://purl.org/rss/1.0/channel> note: explain transitive nature

Arc Selection Patterns

An Arc Selection Pattern specifies a set of criteria that are used to build a list of matching sub-graphs, each consisting of the single triple that the arc participates in. The value-of element uses Arc Selection Patterns to specify which arcs to include in a value evaluation.

The pattern is evaluated against the context graph and any matching arcs are identified. Each matching arc forms the basis of a new sub-graph. The following process is followed for each matching arc:

  1. A new sub-graph is created
  2. The triple containg the the matching arc is added to the sub-graph.
  3. Add the sub-graph to the list of matching sub-graphs along with a reference to the node that is the subject of triple.

Node Selection Pattern Examples

*/*
Selects all arcs in the context graph.
uriref('http://blog.iandavis.com/')/*
Selects all arcs that are attached to a node with uriref <http://blog.iandavis.com/>
*/uriref('http://purl.org/rss/1.0/title')
Selects all arcs with a label of rss:title in the context graph
uriref('http://blog.iandavis.com/')/uriref('http://purl.org/rss/1.0/title')
Selects all arcs with a label of rss:title attached to any nodes with a uriref of <http://blog.iandavis.com/> in the context graph
*/subPropertyOf(uriref('http://purl.org/rss/1.0/title'))
Note: good description required

Node Match Patterns

Template rules identify the nodes to which they apply by using a node match pattern.

The pattern is evaluated against the context graph and the match is deemed to be positive if the number of nodes in the context graph that match the pattern is greater than zero.

Node Match Pattern Examples

Pattern Syntax

Patterns

Patterns consist of a sequence of alternating node and arc patterns specifying a traversal through the context graph. The alternate patterns are separated using forward slashes (/).

pattern ::= nodePattern ( '/' arcPattern ( '/' pattern )? )?

Node Patterns

A node pattern is a set of criteria which is evaluated against each node in a graph. Node patterns consist of a node specifier followed by zero or more conditions.

nodePattern ::= nodeSpecifier condition*

Node Specifiers

A node specifier is a set of criteria which specifies the label of a node. This can be either an asterix (*) which matches any nodes or a uriref which matches any node labelled with that uriref.

The simplest node pattern consists of a single node specifier.

nodeSpecifier ::= '*' | uriref

A uriref may be constructed using the uriref function.

*
Matches any node
uriref('http://blog.iandavis.com/')
Matches any node with the given uriref.

Conditions

Specifiers can be made more specific by adding a condition. A condition specifies a set of criteria that is applied to the each node matching the specifier. Since arc labels can also be nodes in the graph, conditions can also be applied to arc specifiers. The condition is enclosed in square brackets ( [ and ] ) and appended to the specifier. Any number of conditions can be appended and each is applied in turn to the results of the previous condition.

A condition consists of an arc pattern followed by an equals sign (=) followed by an arc value. An arc value can be either an asterix (*) which represents any value, a uriref or a literal value

condition ::= '[' arcPattern '=' arcValue ']'

arcValue ::= '*' | uriref | literal

Arc Patterns

An arc pattern is a set of criteria which is evaluated against each arc in a graph. Arc patterns consist of a arc specifier followed by zero or more arc conditions.

arcPattern ::= arcSpecifier condition*

Arc Specifiers

A arc specifier is a pattern fragment that is applied to arcs in a graph. Like a node specifier the pattern can be either an asterix (*) which matches any arcs or a uriref which matches any arc labelled with that uriref.

arcSpecifier ::= '*' | uriref

An arc specifier must always be used in conjunction with a node specifier (and/or node condition, see below). It is not legal to provide an arc specifier without a node specifier.

Condition Functions

There are a number of helper functions that assist in the specification of conditionals. Apart from uriref and literal they all act as shorthand for more complex expressions.

Text values for parameters are always enclosed in single or double quotes.

uriref

Parameters:

uri
A string specifying the uri

Matches a URI reference (a label on a node or an arc). If the uri parameter is not supplied then this function will match any uriref

type

uriref
A uriref or a string specifying a uri

Specifies that the node or arc matching must have an arc labelled as rdf:type. If uriref is specified then the label on the rdf:type arc must match the uriref supplied.

This is exactly equivalent to: *[uriref('http://www.w3.org/1999/02/22-rdf-syntax-ns#type') = uriref]

If no uriref is specified then this function becomes equivilent to *[uriref('http://www.w3.org/1999/02/22-rdf-syntax-ns#type') = *]

class

Specifies that the node or arc matching must have an arc labelled as rdf:type with a value of rdfs:Class.

This is exactly equivalent to: *[uriref('http://www.w3.org/1999/02/22-rdf-syntax-ns#type') = uriref('http://www.w3.org/2000/01/rdf-schema#Class')]

property

Specifies that the node or arc matching must have an arc labelled as rdf:type with a value of rdfs:Property.

This is exactly equivalent to: *[uriref('http://www.w3.org/1999/02/22-rdf-syntax-ns#type') = uriref('http://www.w3.org/2000/01/rdf-schema#Property')]

literal

Parameters:

value
The literal text to match
lang
The iso language code of the literal

Note: datatyping possibly to be added as a parameter

Specifies a literal with the given value and language. This can be used to match arcs with literal values in conditions. If neither value or lang are specified then this function will match any literal value.

subClassOf

Parameters:

uriref
A uriref (not a literal uri, use the uriref function)

This is exactly equivalent to: *[uriref('http://www.w3.org/2000/01/rdf-schema#subClassOf') = uriref]

subPropertyOf

Parameters:

uriref
A uriref (not a literal uri, use the uriref function)

This is exactly equivalent to: *[uriref('http://www.w3.org/2000/01/rdf-schema#subPropertyOf') = uriref]

The following patterns are equivalent, showing use of the helper functions:

*[uriref('http://www.w3.org/1999/02/22-rdf-syntax-ns#type') = uriref('http://purl.org/rss/1.0/channel')]
*[type() = uriref('http://purl.org/rss/1.0/channel')]
type(uriref('http://purl.org/rss/1.0/channel'))
type('http://purl.org/rss/1.0/channel')

Pattern Examples

*
matches any node
*/*
matches any property of any resource
*/*/*
matches any value of any property
uriref('http://blog.iandavis.com/')
match any node with the given uriref
type(uriref('http://purl.org/rss/1.0/channel'))
match any resource that has a property rdf:type with value <http://purl.org/rss/1.0/channel>
class()
match any resource that has a property rdf:type with value <http://www.w3.org/2000/01/rdf-schema#Class>
property()
match any resource that has a property rdf:type with value <http://www.w3.org/2000/01/rdf-schema#Property>
subClassOf(uriref('http://purl.org/rss/1.0/channel'))
match any resource that has a property rdfs:subClassOf with value <http://purl.org/rss/1.0/channel>
subPropertyOf(uriref('http://purl.org/rss/1.0/title'))
match any resource that has a property rdfs:subPropertyOf with value <http://purl.org/rss/1.0/title>
type(uriref('http://purl.org/rss/1.0/channel'))/*/literal()
match literal nodes that are the value of any property of all resources that have the type rss:channel

Template Elements

Element Namespace

The RDFT namespace has the URI http://blog.iandavis.com/2003/01/rdft

stylesheet

<rt:stylesheet version=number xmlns:rt="http://blog.iandavis.com/2003/01/rdft">
<!-- Content: top-level-elements -->
</rdft:stylesheet>

An stylesheet element must have a version attribute, indicating the version of RDFT that the stylesheet requires. For this version of RDFT, the value should be 1.0.

The stylesheet element may contain the following elements from the RDFT namespace plus any elements from other namespaces:

  • template

template

match
a node match pattern

The template elements specified a template rule. It has a single attribute match which specifies the node match pattern that will cause this rule to be applied. When the rule is fired the parse tree of contained elements is traversed. Each element from a namespace other than the RDFT namespace is copied into the result tree. Any elements in the RDFT namespace trigger further processing as described in this document.

The template element may contain the following elements from the RDFT namespace plus any elements from other namespaces:

  • value-of
  • for-each
  • apply-templates

value-of

select
an arc selection pattern

This element is replaced by the literal value of the arc selection pattern specified in the select attribute. If more than one arc matches the pattern then the literal values of each arc are concatenated. The order in which they are selected is undefined.

The literal value of an arc that points to a non-literal node is determined by recursively concatenating the literal values of all arcs that originate at the node. The order in which the arcs are selected is undefined.

The value-of element may not contain any elements from any namespace.

for-each

select
a node selection pattern

This element uses the node selection pattern specified in the select attribute to build a list of sub-graphs as described in Node Selection Patterns. The elements contained within the for-each element are interpreted as per the rules in the template element for each of the sub-graphs in turn. The order in which the sub-graphs are processed is undefined.

The for-each element may contain the following elements from the RDFT namespace plus any elements from other namespaces:

  • value-of
  • for-each
  • apply-templates

apply-templates

select
a node selection pattern

This element uses the node selection pattern specified in the select attribute to build a list of sub-graphs as described in Node Selection Patterns. The rules in the template document are then evaluated for each of the sub-graphs and the one that matches with the highest priority is interpreted using the sub-graph as the context-graph for that template rule. The order in which the sub-graphs are processed is undefined.

The apply-templates element may not contain any elements from any namespace.

Open Issues

Lots of issues, of which these are only a taster...

  • Starting context graph - need to define
  • Starting context node - need to define, probable as 'unspecified'
  • Import external files into model
  • Analogs of other XSLT elements: if, choose, when, variable, param, named templates
  • Add references to other specs
  • Literal datatyping
  • Incorporate rdf:Seq to determine sequence of processing for-each etc

Permalink: http://blog.iandavis.com/2003/01/rdf-templates-draft-1/

Other posts tagged as rdf

Earlier Posts