SPARQL Template

SPARQL Template Transformations for RDF

29 January 2017

This version: http://ns.inria.fr/sparql-template

Authors:

Olivier Corby <olivier.corby@inria.fr>
Catherine Faron Zucker <faron@i3s.unice.fr>
Fabien Gandon <fabien.gandon@inria.fr>

Abstract

This document defines the syntax and semantics of the STTL language where STTL stands for SPARQL Template Transformation Language. A transformation expressed in STTL describes rules for transforming a source RDF graph into a result text. STTL is an extension of SPARQL 1.1 Query Language.

Table of contents

1 Introduction
2 Transformation Structure
  2.1 Transformation
  2.2 Template
  2.3 Named Template
3 Data Model
  3.1 Result Format
4 Applying Templates
  4.1 Template Processing
  4.2 Result Processing
  4.3 Named Templates
  4.4 STTL Functions
  4.5 Utility Functions
  4.6 SPARQL Functions
5 Tuning Transformation
  5.1 Extension Functions
  5.2 Start Template
  5.3 Profile Template
  5.4 Priority
6 Statements
  6.1 Conditional Processing
  6.2 Recursion
  6.3 Sorting
  6.4 Group
  6.5 Box
  6.6 Format
7 Syntax
  7.1 Template Syntax
  7.2 Transformation Syntax
8 Semantics
9 Use Cases
10 Conclusion

1. Introduction

This document defines the syntax and semantics of the STTL language: SPARQL Template Transformation Language. A transformation expressed in STTL describes rules for transforming a source RDF graph into a result text. STTL is an extension of SPARQL 1.1 Query Language. STTL for RDF is similar in principle to XSLT for XML. An STTL engine takes an RDF graph and a transformation (a set of templates) as input and generates a textual output format as a character stream. Output format may be unstructured text such as natural language, structured text such as Turtle, HTML, XML, Latex, etc. If the RDF graph represents an Abstract Syntax Tree of another language, e.g. SPIN, the transformation engine may generate a concrete syntax, e.g. SPARQL.

 

2 Transformation Structure

STTL defines and uses the prefix and namespace shown below, which is omitted in the rest of the document:

prefix st: <http://ns.inria.fr/sparql-template/>

2.1 Transformation

A transformation is defined a set of templates. A transformation can be defined in two different formats. The first format is a directory that contains the set of templates where each template is written in a separate file with extension .rq. The second format is one RDF/XML file with extension .rul which contains the set of templates where each template in embedded in an RDF/XML markup.

In the process of finding the applicable template, more than one template may be eligible. However, in the general case, only one template will be applied. The first template in the transformation is chosen except if templates have priorities. In this case, the template with the highest priority is chosen.

STTL provides a "hook" to define extension functions that are available within a transformation.

2.2 Template

SPARQL 1.1 Query Language proposes four query forms: select, construct, ask and describe. STTL proposes an additional query form: template. The template where query form is used to specify a text pattern that is instantiated with the results of the where clause. It is similar to the construct clause but generates text instead of generating RDF triples. The text pattern is made of constants (literals) and evaluable expressions (variables, function calls, etc.).

The where clause is executed as a SPARQL query where clause, with focus node bound to variable ?in if any, producing a solution sequence. It must be noted that the from, from named, order by, group by, having, limit, offset and values clauses are available for templates with the same syntax and semantics as SPARQL.

The template clause is instantiated for each solution of the where clause, producing a text for each solution. Variables in the template clause are replaced by their value from the solution, using by default the Turtle syntax. The result of a template is the concatenation of the text results produced by all the solutions. It must be noted that aggregates are available in the template clause with the same semantics as SPARQL. In the case of aggregates, the aggregate operations are performed, possibly with group by, thus producing a new solution sequence. The template clause is evaluated on the solution sequence resulting from the aggregate.

The example below lists all the triples of the current RDF graph in Turtle syntax.

template {
  ?in " " ?p " " ?o " ."
}
where {
  ?in ?p ?o
}

2.3 Named Template

A template can have a name (an URI) and parameters as shown below.

prefix foaf: <http://xmlns.com/foaf/0.1/>
template st:display(?x) {
    st:apply-templates(?y)
}
where {
    ?x foaf:knows ?y
}

 

3 Data Model

The data model used by STTL is the same as that used by SPARQL: RDF Dataset. The data model used by STTL is the RDF Dataset resulting from the parsing of the input RDF document(s) whatever their syntax is: RDF/XML, Turtle, N3, JSON-LD or RDFa. If the triple store is provided with an entailment regime (e.g. RDFS), STTL exploits the entailments in the same way than SPARQL.

3.1 Result Format

The result of a transformation is a text, that is a character stream. The text can be structured (HTML, RDF/XML, XML, etc.), it can represent statements of a language (e.g. Turtle, SPARQL, OWL functional syntax, etc.), it can be natural language, etc.

 

4 Applying templates

4.1 Template Processing

A template in a transformation may apply other templates. This is done using the st:apply-templates extension function. Below is an example of template which generates the functional syntax of an OWL allValuesFrom restriction statement.

template {
  "allValuesFrom(" 
      st:apply-templates(?p) " " 
      st:apply-templates(?c) 
  ")"
}
where {
   ?in a owl:Restriction ;
      owl:onProperty ?p ;
      owl:allValuesFrom ?c .
}

The previous template when applied to :

[] a owl:Restriction ;
      owl:onProperty foaf:knows ;
      owl:allValuesFrom foaf:Person .

generates the text below:

allValuesFrom(foaf:knows foaf:Person)

In the template above, two variables occur in the template clause: ?p and ?c. These variables are recursively processed by the st:apply-templates extension function using the set of templates of the transformation. If no template succeeds, a default format is generated which is the Turtle format. The where clause is the same as in SPARQL, except that variable ?in is bound to the focus node. The focus node is the node that is the argument of the current st:apply-templates function call.

The st:apply-templates function applies the first template in the transformation such that 1) the template were not already applied on the same focus node previously, 2) the where clause, with its ?in variable bound to the focus node, returns a solution sequence that is not empty and 3) the template clause does not raise an error.

Note that the st:apply-templates function can be called in the where part as shown below.

template {
  "allValuesFrom(" ?pp  " " ?cc ")"
}
where {
   ?in a owl:Restriction ;
      owl:onProperty ?p ;
      owl:allValuesFrom ?c .
   bind (st:apply-templates(?p) as ?pp)
   bind (st:apply-templates(?c) as ?cc)   
}

4.2 Result Processing

The result of a template is the concatenation of the texts resulting from the instantiation of the template clause on every solutions of the where clause. By default, a newline character is inserted as separator between text solutions. It is possible to overload the separator using the separator statement, similar to the SPARQL group_concat aggregate separator statement as shown below.

prefix foaf: <http://xmlns.com/foaf/0.1/>
template {
  ?name ; separator = ", "
}
where {
  ?in foaf:name ?name
}

4.3 Named Templates

A named template is called by name with parameter values using the st:call-template function. When several parameters occur, parameter passing is done by position (i.e. not by name).

prefix foaf: <http://xmlns.com/foaf/0.1/>
template {
    st:call-template(st:display, ?in)
}
where {
    ?in a foaf:Person
}

4.4 STTL Functions

In order to apply templates, the language provides a set of SPARQL extension functions. Running a transformation engine on a set of templates is done by an initial call to st:apply-templates-with in a SPARQL query (or a template) where the st-uri argument is the URI of the transformation. This function can also be used to apply another transformation within a transformation. Hence a complex transformation can be split into simpler ones. The uri argument of st:call-template is the name of a template. The term argument is the focus node, it is an RDF term.

In some cases, it is necessary to apply several templates in order to transform a focus node. In this case, the st:apply-templates-all function may be used. The result of st:apply-templates-all is the concatenation of the results of all the templates that succeed.

The st:apply-templates-graph functions enables the transformer to focus on a specific named graph. The graph-uri argument is the name of a graph.

The st:call-template functions enables the transformer to call a specific named template. The uri argument is the name of a named template.

st:apply-templates(term)

st:apply-templates-with(st-uri)
st:apply-templates-with(st-uri, term)

st:apply-templates-all(term)
st:apply-templates-with-all(st-uri, term)

st:apply-templates-graph(graph-uri)
st:apply-templates-with-graph(st-uri, graph-uri)

st:call-template(uri, term_1, .., term_n)
st:call-template-with(st-uri, uri, term_1, .., term_n)

4.5 Utility functions

There are aditional utility functions.

st:turtle(term)

st:format(text-format, term, ...)

st:number()

st:nl()

st:turtle returns the Turtle format of an RDF term.
st:format given a text pattern with %s text variables and expressions, returns a formatted string.
st:number returns a number corresponding to the solution position.
st:nl returns a new line and take indentation defined by box into account.

4.6 SPARQL Functions

SPARQL functions can be used in the template clause.

prefix foaf: <http://xmlns.com/foaf/0.1/>
template {
   "The name of " xsd:string(?in) " is " xsd:string(?n) "."
}
where {
   ?in foaf:name ?n
}

 

5 Tuning Transformation

5.1 Extension Functions

STTL comes with a simple formalism to define SPARQL extension functions. The function clause enables users to define a function with an URI as name and a list of parameter variables. The body of the function is defined using SPARQL filter language.

function st:display(?x) {
  if (isURI(?x), 
    concat("<", str(?x), ">"),
    str(?x))
}

function st:fac(?n) {
  if (?n = 0, 1, ?n * st:fac(?n - 1))
}

5.2 Start Template

As there are no natural root nodes in a graph, we provide the possibility to define a specific start template that determines the nodes to start with. The start template, if any, is the st:start named template. Otherwise, the first template of the transformation that succeeds is applied.

prefix foaf: <http://xmlns.com/foaf/0.1/>
template st:start {
  st:apply-templates(?x)
}
where {
  ?x a foaf:Person
}

5.3 Profile Template

The st:profile named template enables to overload the default behaviour of the transformer (the transformation engine). This template is not executed, it is considered at compile time. The st:profile template enables users to define extension functions that are available for all templates of the transformation. Function definitions are listed below the st:profile template definition (which is empty).

st:process is a predefined function that specifies the processing of variables in the template clause. The default behaviour is to call st:turtle and it can be overloaded. In the example below, st:apply-templates is called on blank nodes and st:turtle is called on URIs and literals.

template st:profile {}
where {}

function st:process(?x) {
  if (isBlank(?x), st:apply-templates(?x), st:turtle(?x))
}

5.4 Priority

In the case where several templates may succeed, it may be necessay to sort templates according to an explicit priority. Smaller numbers represent higher priority. Pragma is a syntactic extension than enables to define priority. It may be used in the future to define new features.

template { ... }
where    { ... }
pragma   { st:template st:priority 1 }

 

6 Statements

6.1 Conditional Processing

Conditional processing is done using SPARQL if then else filter expression.

prefix foaf: <http://xmlns.com/foaf/0.1/>
template {
  if (?age >= 18, 
    st:call-template(st:adult, ?in),
    st:call-template(st:child, ?in))
}
where {
  ?in foaf:age ?age
}

6.2 Recursion

The combined use of if, st:call-template and recursion enables to implement powerful processing such as printing the development of n!.

template st:fac(?n) {
   if (?n = 0, 1, 
     concat(?n, ".", st:call-template(st:fac, ?n - 1)))
}
where {}

6.3 Sorting

Sorting is done using SPARQL order by clause.

prefix foaf: <http://xmlns.com/foaf/0.1/>
template {
    st:apply-templates(?in)
}
where {
  ?in a foaf:Person ;
    foaf:name ?name
}
order by ?name

6.4 Group

The group statement is syntactic sugar for group_concat() aggregate operation, except that it can have several arguments. In addition, it can have a separator which acts in the same way as SPARQL group_concat aggregate separator. Below is an example that concatenates the elements of a list.

template {
  "list("
     group { ?elem }
  ")"
}
where {
  ?in rdf:rest*/rdf:first ?elem
}

6.5 Box

Box enable to increment the indentation of the output character stream when st:nl() is used.

template {
  "list("
     box {
       group { ?elem st:nl() }
     }
  ")"
}
where {
  ?in rdf:rest*/rdf:first ?elem
}

6.6 Format

Format enable to specify a string pattern with text variables (%s) and a list of expressions. Text variables are replaced by the values of expressions.

template {
  format {
    "<h1>%s</h1><p>%s</p>"
    ?title ?text
  }
}
where {
  ?in ex:title ?title ; ex:text ?text
}

 

7 Syntax

7.1 Template Syntax

We provide the syntax of SPARQL template, based on SPARQL 1.1 grammar.

Template ::= 
   Prologue 
   TemplateClause
   DatasetClause*
   WhereClause 
   SolutionModifier
   ValuesClause
   Pragma
   Function*
   
TemplateClause ::=
   'template' NameArg ? '{' 
     TExpression * 
     Separator ? 
   '}'
   
TExpression ::= PrimaryExpression | Box | Format | Group
   
NameArg ::= (iri VarList) | VarList
   
VarList ::= '(' Var * ')'
             
Group ::= 
  'group' ( 'distinct' ) ? '{' 
   ( PrimaryExpression | Box | Format ) * 
   Separator ? 
   '}'
   
Box ::= 
  'box'  '{' TExpression  * '}'
   
Format ::= 
    'format' '{' 
        PrimaryExpression
        TExpression +
    '}'
               
Separator ::= ';' 'separator' '=' String

Pragma ::= ( 'pragma' '{' Triple+ '}' ) ?

Function ::= 'function' iri VarList '{' PrimaryExpression '}'

7.2 Transformation Syntax

Syntax of the RDF/XML document for tranformations. Each template must define its prefix and namespaces.

<rdf:RDF  
  xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' 
  xmlns='http://ns.inria.fr/sparql-template/'>

<rule>
<body>
<![CDATA[
prefix st: <http://ns.inria.fr/sparql-template/>
template st:list(?l) {
  ?e
}
where {
  ?l rdf:rest*/rdf:first ?e
}
]]>
</body>
</rule>

<rule>
<body>
...
</body>
</rule>

</rdf:RDF>

 

8 Semantics

SPARQL Templates are compiled as select-where SPARQL queries where variables in the template clause are replaced by a call to the st:process extension function. Its default behaviour is to call st:turtle. When st:process is bound to st:apply-templates in the profile, it implements the recursive call to the transformation engine. This function plays a similar role as the xsl:apply-templates clause in XSLT. Its behavior consists in executing templates one by one from the set of templates until one of them succeeds. The result of the st:apply-templates function call is the result of this successful template execution.

A template succeeds if the evaluation of the where clause returns solution(s) and if the evaluation of the template clause does not raise an error. An error may be caused by an unbound variable.

The focus node is the node that the transformation engine is processing at the current time. It is bound to a distinguished ?in variable the value of which is determined at run time by a process equivalent to the one shown below where the st:getFocusNode() function represents the focus node value determined from the environment.

The template below:

template {
  "allValuesFrom(" ?p " " ?c ")"
}
where {
   ?in a owl:Restriction ;
      owl:onProperty ?p ;
      owl:allValuesFrom ?c .
}

is compiled into a select-where SPARQL query as shown below. The st:concat function is similar to the SPARQL concat function.

select 
  (st:concat (
    "allValuesFrom(", 
     st:process(?p), " ", st:process(?c), ")") 
   as ?out)
where {
   bind (st:getFocusNode() as ?in) .
   ?in a owl:Restriction ;
      owl:onProperty ?p ;
      owl:allValuesFrom ?c .
}

Executing a template consists first in executing the where part which results in a solution sequence (i. e. variable bindings). Then the select clause is executed, providing a solution sequence extended with the projected variable ?out. This is standard SPARQL query execution. To finish, an additional group_concat(?out) aggregate operation is performed on the solution sequence, resulting into one solution where all values of the ?out variable are concatenated into a string value. This is the final result of the template and this is the result returned by the st:apply-templates function. Hence, it is possible to implement a STTL engine on top of a SPARQL interpreter using extension functions.

The group statement:

template {
   "list("
      group { ?x ?y }
   ")"
}
where {
  ...
}

is compiled as:

select  
   (st:concat("list(", group_concat(concat(st:process(?x), st:process(?y))), ")") 
    as ?out)
where {
  ...
}

 

9 Use Cases

We present some use cases for STTL.

RDF

List the content of a graph in Turtle syntax.

template {
  ?x " " ?p " " ?y "."
}
where {
  ?x ?p ?y
}
order by ?x ?p ?y

List the named graphs of a Dataset in Trig syntax.

template {
  "graph " ?g " {\n" 
      group { ?x " " ?p " " ?y ".\n" }
  "}"
}
where {
  graph ?g { ?x ?p ?y }
}
group by ?g
order by ?g 

HTML

Generate an HTML table with the triples of the RDF graph.

template {
  format {
   """
   <html>
   <body>
   <table>%s</table>
   </body>
   </html>
   """
   
   group { 
    format {
       "<tr><td>%s</td><td>%s</td><td>%s</td></tr>\n"       
       ?s ?p ?o
    }
   }
  }
}
where  {
   ?s ?p ?o 
}
order by ?s ?p ?o

 

10 Conclusion

SPARQL Template Transformation Language aims at generating presentation format for RDF graphs. It is designed as an extension of SPARQL 1.1 Query Language. STTL is available in the Corese Semantic Web Factory and it is used in the Corese Web server. Preliminary works show that STTL can also be used to perform constraint checking with templates that return boolean values instead of text.

 

References

[RDF]
RDF 1.1 Concepts and Abstract Syntax, Graham Klyne, Jeremy J. Carroll, Brian McBride. W3C Recommendation, February 2014

[SPARQL]
SPARQL 1.1 Query Language, Steve Harris, Andy Seaborne. W3C Recommendation, March 2013

[XSLT]
XSL Transformations (XSLT) Version 2.0, Michael Kay. W3C Recommendation, March 2007

Valid XHTML 1.0 Transitional