Façade-X Data Access in SPARQLSERVICE clause.This document specifies how a Façade-X view of a heterogeneous resource is accessed from within a
SPARQL query. It defines the SERVICE clause and IRI scheme through which an engine is asked to
build the Façade-X representation of a resource, the options (properties) that control how the
resource is interpreted, and the magic properties that support querying the resulting containers.
It is a companion to the Façade-X Concepts and Metamodel and
Façade-X RDF Vocabulary documents: the former defines the model, the latter its RDF
terms, and this document defines how that RDF is obtained and queried in SPARQL.
This document is currently in active development. The mechanism described here is the one provided by the reference implementation, SPARQL Anything; the naming of the IRI scheme in particular is expected to be revisited before standardisation (see the Issues section).
The metamodel and RDF vocabulary documents describe what a Façade-X view of a resource is: a single root container, holding slots keyed by number or string, whose values are literals or further containers. This document describes how a SPARQL query obtains and queries such a view.
The mechanism is a magic SERVICE clause. Rather than materialising the Façade-X RDF of a
resource ahead of time, a query names the resource inside a SERVICE block whose IRI carries a
reserved scheme. A conforming engine intercepts that clause, produces the Façade-X representation of
the named resource according to the metamodel and RDF vocabulary, and
evaluates the enclosed graph pattern against it. The resource is thus queried in place, as ordinary
RDF, with no separate transformation step.
| Prefix | Namespace | Description |
|---|---|---|
| fx | http://sparql.xyz/facade-x/ns/ | The Façade-X vocabulary, including the option and magic properties defined here |
| xyz | http://sparql.xyz/facade-x/data/ | The default namespace for properties and classes derived from source data |
| rdf | http://www.w3.org/1999/02/22-rdf-syntax-ns# | Used for container-membership properties (rdf:_1, rdf:_2, …) |
The reserved IRI scheme is currently x-sparql-anything:, the scheme used by the reference
implementation. A vendor-neutral scheme name is expected to be chosen before this document reaches
Recommendation status; until then, the implementation-specific scheme is used throughout.
This document types the root container fx:Root, in agreement with the
RDF vocabulary document. Some implementations currently emit the lowercase
fx:root; the casing is to be reconciled across the specifications and implementations.
SERVICE clauseA Façade-X view is requested through a SPARQL SERVICE block whose IRI uses the reserved scheme
x-sparql-anything:. The general form is:
SERVICE <x-sparql-anything:[OPTIONS]> {
[GROUP GRAPH PATTERN]
}
An engine that conforms to this specification MUST, on encountering a SERVICE block whose IRI uses
the x-sparql-anything: scheme:
fx:location, fx:content,
or fx:command — MUST be given;SERVICE invocation.The resulting representation is a single Façade-X data source: one container typed
fx:Root, reachable from which are its slots, values, and nested containers. Where
a resource yields more than one data source, each is produced in its own named graph, as described
in Named Graphs.
Options are supplied to the engine in either of two modalities, which MAY be combined.
Options may be written in the SERVICE IRI itself, after the scheme, as a comma-separated list of
name=value pairs:
SERVICE <x-sparql-anything:location=https://example.org/people.json,media-type=application/json> {
?root a fx:Root ; xyz:name ?name .
}
As a shorthand, a service IRI consisting of the scheme followed by a single argument with no
name=value form treats that argument as the source fx:location (or fx:content):
SERVICE <x-sparql-anything:https://example.org/people.json> {
?root a fx:Root ; xyz:name ?name .
}
Options may instead be given as triples inside the SERVICE block. Such triples MUST have the
reserved resource fx:properties as subject, an option property fx:[NAME] as predicate, and a
literal or a variable as object:
SERVICE <x-sparql-anything:> {
fx:properties fx:location "https://example.org/people.json" ;
fx:media-type "application/json" .
?root a fx:Root ; xyz:name ?name .
}
Using a variable as the object of an option triple allows the option value to be bound elsewhere in
the query, for example from another SERVICE clause or from the enclosing query's bindings.
The two modalities MAY be mixed within a single SERVICE clause; options given as triples take
precedence over options of the same name given in the IRI. An implementation MAY additionally accept
options from outside the query (for example, a command-line default); such external options are
overridden by options given in the IRI, which are in turn overridden by options given as triples.
Exactly one source option MUST be provided. It identifies the resource whose Façade-X view is to be queried.
| Option | Value | Description |
|---|---|---|
| fx:location | A URL, or an absolute or relative file-system path | The resource to be interpreted as a Façade-X data source. |
| fx:content | A literal | Inline content to be interpreted directly, in place of a located resource. |
| fx:command | A literal | An external command line whose standard output is interpreted, according to fx:media-type. |
The following options control how the source is mapped onto the Façade-X model. All are optional.
| Option | Value | Default | Description |
|---|---|---|---|
| fx:media-type | A media type | Inferred from the file extension | The media type of the source, selecting how it is interpreted. Required when it cannot be inferred (e.g. for fx:content or fx:command). |
| fx:namespace | An IRI | http://sparql.xyz/facade-x/data/ | The namespace used to mint properties (string slots) and classes (types) from source keys and tags. |
| fx:blank-nodes | true | false | true | Whether containers are represented as blank nodes. When false, containers are given minted IRIs derived from fx:root. |
| fx:root | An IRI | Derived from the source | The IRI of the root container, also used as the base for minting graph and container IRIs. Defaults to the location, or to a hash of the content or command. |
| fx:trim-strings | true | false | false | Trim leading and trailing whitespace from string values. |
| fx:null-string | A literal | — | Suppress any triple whose object value would equal the given string. |
| fx:use-rdfs-member | true | false | false | Use the property rdfs:member in place of the numbered container-membership properties rdf:_1, rdf:_2, … |
Formats define further, format-specific options (for example CSV delimiters and header handling, or JSON and XML path expressions). These are defined alongside each format and are out of scope for this document.
The following options affect how the representation is built and evaluated, but not the mapping itself. All are optional.
| Option | Value | Description |
|---|---|---|
| fx:strategy | 0 | 1 | Triplification strategy: 0 materialises all triples; 1 materialises only triples that can match a pattern in the query. |
| fx:ondisk | A directory path | Use an on-disk graph stored at the given directory, allowing very large sources to be processed without exhausting memory. |
| fx:ondisk.reuse | true | false | When an on-disk graph is used, reuse a previously created one rather than rebuilding it. |
| fx:slice | true | false | Process the source in slices, evaluating the graph pattern against each slice in turn, so that large sources can be streamed. |
| fx:audit | true | false | Emit an additional auditing graph (<http://sparql.xyz/facade-x/data/audit>) describing the triplification. |
Beyond the terms defined by the RDF vocabulary, an engine recognises a small number of
magic properties within a Façade-X SERVICE block. These are not asserted triples but query-time
constructs the engine evaluates specially.
The property fx:anySlot matches any container-membership slot of a container. A triple pattern
?c fx:anySlot ?v binds ?v to each value held by a numbered slot (rdf:_1, rdf:_2, …) of the
container ?c, regardless of its position. It lets a query traverse the members of a container
without enumerating their indices.
PREFIX fx: <http://sparql.xyz/facade-x/ns/>
PREFIX xyz: <http://sparql.xyz/facade-x/data/>
SELECT ?name ?pet WHERE {
SERVICE <x-sparql-anything:> {
fx:properties fx:location "people.json" .
?root a fx:Root ;
xyz:name ?name ;
xyz:pets ?pets .
?pets fx:anySlot ?pet .
}
}
Engines additionally provide functions over container-membership properties — for example
fx:cardinal(?p), which returns the numeric index of a membership property, and fx:before(?a, ?b)
and fx:after(?a, ?b), which compare the order of two membership properties. A fuller library of
helper functions is provided by implementations and is out of scope for this document.
Interpreting an inline JSON literal, with the media type stated explicitly because it cannot be inferred from a file extension:
PREFIX fx: <http://sparql.xyz/facade-x/ns/>
PREFIX xyz: <http://sparql.xyz/facade-x/data/>
SELECT ?name ?surname WHERE {
SERVICE <x-sparql-anything:> {
fx:properties fx:content "{\"name\":\"Vincent\",\"surname\":\"Vega\"}" ;
fx:media-type "application/json" .
?root a fx:Root ;
xyz:name ?name ;
xyz:surname ?surname .
}
}
Requesting minted IRIs instead of blank nodes for containers, using the IRI modality for the source and a triple for the remaining option:
PREFIX fx: <http://sparql.xyz/facade-x/ns/>
PREFIX xyz: <http://sparql.xyz/facade-x/data/>
CONSTRUCT { ?s ?p ?o } WHERE {
SERVICE <x-sparql-anything:location=https://example.org/people.json> {
fx:properties fx:blank-nodes false .
?s ?p ?o .
}
}