-
Notifications
You must be signed in to change notification settings - Fork 6
Linked Data Templates
See the Linked Data Templates for a detailed specification of how templates are defined and executed
AtomGraph sitemap ontology contains Linked Data Templates (LDTs) expressed in RDF/OWL. The ontology is defined like this:
: a ldt:Ontology ;
owl:imports ct:, sp: ;
owl:versionInfo "1.0.0" ;
rdfs:label "Example templates" .
LDT ontologies can import other ontologies (LDT or not) using owl:imports
. A common case is importing some of the built-in ontologies.
LDT template matches a class of document resources that:
- their URI identifiers share the same URI pattern (match specified URI template)
- their RDF representation was generated from the same SPARQL query
However it is not a "class" in an OWL sense.
Correspondingly, ldt:match
and ldt:query
are two required properties for a template:
:LabelResources a ldt:Template ;
ldt:match "/resources/labelled" ;
ldt:query :DescribeLabelResources ;
rdfs:isDefinedBy : .
rdfs:isDefinedBy
identifies which LDT ontology the template belongs to. Templates can also have additional properties.
Templates can extend each other using the ldt:extends
property. Extending templates inherit LDT annotation properties from super-templates, unless they override inheritance by defining their own property.
We modify our example to extend a built-in template and override its properties:
:LabelResources a ldt:Template ;
ldt:extends ct:Document ;
ldt:match "/resources/labelled" ;
ldt:query :DescribeLabelResources ;
ldt:param :LabelParam ;
rdfs:label "Labelled resource container" ;
rdfs:isDefinedBy : .
ct:Document
is the lowest-level built-in template. In this example the sub-template overrides all of super-template's properties so the inheritance has no effect.
AtomGraph Processor is using the JAX-RS @Path
URI template syntax, which is based on Java-style regexp pattern. JAX-RS defines a priority algorithm which LDT is using to select the best match even if the request URI is matching multiple templates. For example, a more specific /resources/labelled
takes precedence over the catch-all /{path: .*}
.
AtomGraph Processor is using TopBraid SPIN API to store and manage SPARQL queries as RDF. Queries are instances of SPIN query class, e.g. of sp:Describe
or sp:Construct
. For example:
:DescribeLabelResources a sp:Describe ;
sp:text """
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX dct: <http://purl.org/dc/terms/>
DESCRIBE ?this ?resource WHERE {
{
SELECT ?resource
WHERE {
?resource rdfs:label|dct:title ?label .
FILTER isURI(?resource) .
}
} .
}""" ;
rdfs:isDefinedBy : .
SPIN also allows using instances of SPIN Templates wherever a query is expected (they are known as "template calls").
Read more about SPIN - SPARQL Inferencing Notation.
Templates can have parameters:
:LabelParam a ldt:Parameter ;
rdfs:label "Label parameter" ;
spl:predicate :label ;
spl:optional true ;
spl:valueType xsd:string ;
rdfs:isDefinedBy : .
Parameters can be optional or mandatory and can define a value type. The local name of the predicate is the name by which it can be referenced in the URL query string, i.e. label
in this case. A value provided for a parameter is called an argument, e.g. ?label=foo
.
Like in SPIN API, ?this
variable has a special meaning in AtomGraph. When processing SPARQL query, LDT always sets values to the following variables:
- ?this
- the absolute URI of the request (excluding query string)
For example, if a template is with a query DESCRIBE ?this
, what will be executed is DESCRIBE <http://localhost:8080/>
if request to http://localhost:8080 matches this template.
Moreover, template parameter arguments become query bindings as well.
Lets consider our :LabelResources
template and assume that our LDT server's base URI is http://localhost:8080/
.
During request processing in Processor, if the http://localhost:8080/resources/labelled?label=foo
URI is dereferenced, the following query will be executed on the SPARQL backend:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX sioc: <http://rdfs.org/sioc/ns#>
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX dct: <http://purl.org/dc/terms/>
DESCRIBE <http://localhost:8080/resources/labelled> ?resource WHERE {
{
SELECT ?resource
WHERE {
?resource rdfs:label|dct:title "foo" .
FILTER isURI(?resource) .
}
} .
}
As you can see, ?this
has been bound to the request URI, and ?label
has been bound to the argument value foo
.
Without the argument value present, ?label
would be bound and would remain a variable.
For user interface support, see AtomGraph Web-Client.