Skip to content
This repository

Many RDF toolkits provide SPARQL/Update functionality and move from simple query operations to more powerful data manipulation. SPARQLScript goes another step further and enables or simplifies the implementation of

  • semantic Mashups,
  • custom, portable rule and inference scripts using a SPARQL-based syntax
  • Output templates for RDF data and SPARQL query results
  • RDF/SPARQL-driven Yahoo! Pipes-like systems

SPARQLScript is meant to

  • look and feel like a simple scripting language (i.e. it's not purely declarative)
  • re-use SPARQL syntax where possible (ARC feedback suggests that SPARQL is probably the most intuitive SemWeb syntax for Not-Yet-SemWeb developers. Many ARC users never studied the SPARQL spec and still find their way around with SQL knowledge and some examples)
  • allow the intuitive combination and processing of native SPARQL result types such as record sets (SELECT), RDF graphs (CONSTRUCT, DESCRIBE), and TRUE/FALSE (ASK)

Endpoint Selection

SPARQLScript allows the specification of target SPARQL/SPARUL/SPARQL+ endpoints which should be used for queries. A SPARQLScript processor may fall back to a default endpoint or local SPARQL store if no endpoint is defined in the script.

ENDPOINT <http://dbpedia.org/sparql>
SELECT ...

Query Chaining

SPARQLScript allows the sequential execution of SPARQL queries.

LOAD <http://example.com/g1>
LOAD <http://example.com/g2>
SELECT * WHERE { ... }
...

Re-usable prefixes

PREFIX declarations have a script-wide scope and can be shared by multiple queries.

PREFIX foaf: <http://...>
SELECT ?name WHERE { ?s foaf:name ?name}
SELECT ?nick WHERE { ?s foaf:nick ?nick}

Variable Assignments

Variables can be used to combine the results from one operation with those from another one.

$doc := CONSTRUCT ...
$bool := ASK ...
$rows := SELECT ...
$text := "foo bar baz"
$text2 := $text

(Assignments work with either ":=" or just "=".)

It is possible to merge the values of two variables:

$rows1 = SELECT ...
$rows2 = SELECT ...
$rows = $rows1 + $rows2

Placeholders and structured variables

SPARQLScript re-uses a simple and widely deployed notation for placeholder definitions that can be injected in scripts and strings. Property paths and extended syntax is supported for certain structures such as dates (via NOW), GET/POST arguments, or string manipulation.

# very simple
$foo := "Foo"
$bar := ${foo} # $bar is now "Foo" (and yes, we could have simply used $bar = $foo)
# query placeholder
$name := "John Doe"
SELECT * WHERE {?person foaf:name "${name}"} # ${name} will be replaced with "John Doe" before the query is evaluated
# pre-defined constant NOW with offset functionality
SELECT * WHERE {?s dc:date ?date . FILTER ($date < "${NOW - 2h}") }
# access to GET and POST
$my_arg = ${GET.my_arg}
# property paths
$items = SELECT * WHERE {?item a rss:item ; rss:title ?title . };
$first_title = ${items.0.title}
# string concatenation
$str = "Hello"
$str = "${str} World"
# string manipulation (1st argument = regular expression)
$str = ${str.replace("/world/i", "Mom")}
# URL-encoding
$str = ${str.urlEncode("get")} # space to "+"
$str = ${str.urlEncode("post")} # space to "%20" etc.

Branches

SPARQLScript supports conditional evaluation of script blocks:

$exists := ASK ...
IF ($exists) {
 DELETE FROM ...
}
ELSE {
 INSERT INTO ...
}

Loops

SPARQLScript supports iterating through query result sets:

$items := SELECT * WHERE {?item a rss:item ; rss:title ?title . };
FOR ($row in $items) {
  $title := ${row.title}
  $uri := ${row.item}
}

Output Templating

Stand-alone SPARQL/Turtle literals are added to the SPARQLScript processor's output buffer. This simple method to create custom results can be combined with the other features such as loops and placeholders:

$items = SELECT * WHERE {?item a rss:item ; rss:title ?title . };

$size = ${items.size}
IF ($size) {
  """ I found ${items.size} items: <ul> """
  FOR ($item in $items) {
    "<li>${item.title}</li>"
  }
  " </ul> "
}
ELSE { " no items found "}

If a recordset or array is used in a template, the SPARQLScript processor will try to auto-detect the target format and serialize the given array.

$res = DESCRIBE <http://example.com/foaf.rdf#self>
# generate an RDF document 
# (JSON, XML, Turtle, depending on Accept headers or GET parameter "format")
"${res}"

SPARQL/SPARQL+ Grammar Changes and Additions

Script ::= (Query | EndpointDecl | PrefixDecl | Assignment | IFBlock | FORBlock | String | FunctionCall)*

EndpointDecl ::= 'ENDPOINT' IRI_REF

Assignment ::= Var (':=' | '=') ( Query | String | Var | Placeholder | VarMerge) ';'?

IFBlock ::= 'IF' BrackettedExpression '{' Script '}' ( 'ELSE' '{' Script '}')?

FORBlock ::= 'FOR' '(' Var 'IN' Var ')' '{' Script '}'

Placeholder ::= ('$' | '?') '{' [^}]* '}'

VarMerge ::= Var '+' Var

Using SPARQLScript in ARC

ARC's SPARQLScript processor is instantiated like the RDF Store component. If you are going to work with external SPARQL endpoints only, you don't need to define a store (or database connection). The number of queries or general script operation can be limited (see snippet below).

/* ARC2 static class inclusion */ 
include_once('path/to/arc/ARC2.php');

/* configuration */ 
$config = array(
  /* db */
  ...
  /* store name */
  ...
  /* sparqlscript */
  'sparqlscript_default_endpoint' => 'http://...|local', /* uses defined store if set to "local" */
  'sparqlscript_max_operations' => 100, /* queries, assignments, endpoint declarations */
  'sparqlscript_max_queries' => 10 /* restricts the allowed number of queries */
);

/* instantiation */
$ssp = ARC2::getSPARQLScriptProcessor($config);

/* script evaluation */
$scr = '
  PREFIX foaf: <http://xmlns.com/foaf/0.1/> 
  PREFIX dbpedia2: <http://dbpedia.org/property/> 

  ENDPOINT <http://dbpedia.org/sparql>

  $rows = SELECT ?person ?name ?birth WHERE { 
    ?person dbpedia2:birthPlace <http://dbpedia.org/resource/Berlin> .
    ?person dbpedia2:birth ?birth .
    ?person foaf:name ?name .
  }
  LIMIT 10
  ...
';

$ssp->processScript($scr);
echo $ssp->env['output'];

References

Something went wrong with that request. Please try again.