Lisez-moi S.V.P. 

W3C

Langage d'interrogation SPARQL pour RDF

Recommandation du W3C du 15 janvier 2008

Cette version :
http://www.w3.org/TR/2008/REC-rdf-sparql-query-20080115/
Dernière version :
http://www.w3.org/TR/rdf-sparql-query/
Version précédente :
http://www.w3.org/TR/2007/PR-rdf-sparql-query-20071112/
Rédacteurs :
Eric Prud'hommeaux, W3C <eric@w3.org>
Andy Seaborne, Hewlett-Packard Laboratories, Bristol <andy.seaborne@hp.com>

Veuillez consulter la page des errata de ce document, laquelle peut contenir des corrections normatives.

Cf. aussi d'éventuelles traductions.


Résumé

RDF est un format de données de graphe orienté et étiqueté pour représenter des informations dans le Web. Cette spécification définit la syntaxe et la sémantique du langage d'interrogation SPARQL pour RDF. SPARQL peut être utilisé pour exprimer des interrogations à travers diverses sources de données, que les données soient stockées nativement comme RDF ou vues comme du RDF via un logiciel médiateur (middleware). SPARQL est capable de rechercher des motifs de graphe (graph patterns) obligatoires et optionnels ainsi que leurs conjonctions et leurs disjonctions. SPARQL gère également le test extensible des valeurs et la contrainte des interrogations par un graphe RDF source. Les résultats des interrogations SPARQL peuvent être des ensembles de résultats ou des graphes RDF.

Statut de ce document

Cette section décrit le statut de ce document au moment de sa publication. D'autres documents peuvent venir le remplacer. On peut trouver une liste des publications actuelles du W3C et la dernière version de ce rapport technique dans l'index des rapports techniques du W3C à http://www.w3.org/TR/.

Ceci est une recommandation du W3C.

Ce document a été examiné par des membres du W3C, par des développeurs de logiciels, et par d'autres groupes du W3C et des tiers intéressés, et a été approuvé par le Directeur comme recommandation du W3C. C'est un document stable qui peut être utilisé comme document de référence ou cité par un autre document. Le rôle du W3C en produisant la recommandation est d'attirer l'attention sur la spécification et d'en promouvoir le large déploiement. Cela participe à la fonctionnalité et à l'interopérabilité du Web.

Les commentaires à propos de ce document sont à envoyer à public-rdf-dawg-comments@w3.org, une liste de diffusion avec des archives publiques. Les questions et commentaires à propos de SPARQL non liés à cette spécification, y compris les extensions et les caractéristiques, peuvent être débattus sur la liste de diffusion public-sparql-dev@w3.org (archives publiques).

Ce document a été produit par le groupe de travail RDF Data Access, sous l'égide de l'activité Semantic Web du W3C. La première publication de ce document en tant que version préliminaire a eu lieu le 12 octobre 2004, et le groupe de travail a traité beaucoup de commentaires reçus et de problèmes depuis. Il y a eu deux changements répertoriés depuis la recommandation proposée de novembre 2007.

Le rapport de mise en œuvre du langage d'interrogation SPARQL pour RDF du groupe de travail démontre que les objectifs de mises en œuvre interopérables fixés dans la recommandation candidate d'avril 2006 ont été atteints.

Le groupe de travail Data Access a ajourné 12 questions, dont les fonctions agrégées et un langage de mise à jour.

Ce document a été produit par un groupe agissant sous couvert de la politique de brevets du W3C du 5 février 2004. Le W3C tient une liste publique des divulgations de brevets effectuées en rapport avec les produits livrables du groupe ; cette page contient également des instructions pour divulguer un brevet. Quiconque a connaissance véritable d'un brevet qu'il estime contenir des revendications essentielles doit divulguer cette information conformément à la section 6 de la politique de brevets du W3C.


Table des matières

Annexes


1 Introduction

RDF est un format de données de graphe orienté et étiqueté pour représenter des informations dans le Web. RDF est souvent utilisé pour représenter, entre autres choses, des informations personnelles, des réseaux sociaux, des métadonnées à propos d'artefacts numériques ainsi que fournir un moyen d'intégrer des sources d'information disparates. Cette spécification définit la syntaxe et la sémantique du langage d'interrogation SPARQL pour RDF.

Le langage d'interrogation SPARQL pour RDF est conçu pour satisfaire aux cas d'utilisation et aux exigences identifiés par le groupe de travail RDF Data Access dans Cas d'utilisation et exigences de l'accès aux données RDF [UCNR].

Le langage d'interrogation SPARQL est étroitement lié aux spécifications suivantes :

1.1 Plan du document

Sauf indication contraire dans le titre de la section, toutes les sections et annexes dans ce document sont normatives.

La section 1 du document introduit la spécification du langage d'interrogation SPARQL. Elle présente l'organisation de ce document de spécification et les conventions observées tout au long de la spécification.

La section 2 de la spécification introduit le langage d'interrogation SPARQL soi-même via une série d'exemples d'interrogations et de résultats d'interrogation. La section 3 poursuit l'introduction du langage d'interrogation avec d'autres exemples qui démontrent l'aptitude de SPARQL à exprimer des contraintes sur les termes RDF apparaissant dans les résultats d'interrogation.

La section 4 présente le détail de la syntaxe du langage d'interrogation SPARQL. Elle accompagne la grammaire complète du langage et définit les structures grammaticales représentant les adresses IRI, les nœuds anonymes (blank nodes), les littéraux (literals) et les variables. La section 4 définit également la signification de plusieurs structures grammaticales utilisées comme sucre syntaxique pour des expressions plus verbeuses.

La section 5 introduit les motifs de graphe élémentaires (basic graph patterns) et les motifs de graphe de groupe (group graph patterns), qui sont les éléments d'assemblage à partir desquels sont construits des motifs d'interrogation (query patterns) SPARQL plus complexes. Les sections 6, 7 et 8 présentent les structures combinant les motifs de graphe SPARQL en des motifs de graphe plus grands. En particulier, la section 6 introduit la capacité à rendre optionnels des morceaux d'une interrogation ; la section 7 introduit la capacité à exprimer la disjonction de motifs de graphe alternatifs ; la section 8 introduit la capacité à contraindre des morceaux d'une interrogation à des graphes sources particuliers. La section 8 présente également le mécanisme de SPARQL pour définir les graphes sources d'une interrogation.

La section 9 définit les structures qui affectent les solutions d'une interrogation en triant, découpant, projetant, limitant et supprimant les copies (duplicates) d'une séquence de solutions.

La section 10 définit les quatre types d'interrogation SPARQL produisant des résultats de formes différentes.

La section 11 définit le système de test des valeurs extensibles de SPARQL. Elle présente également les fonctions et opérateurs utilisables pour contraindre les valeurs apparaissant en résultat d'une interrogation.

La section 12 est une définition formelle de l'évaluation des motifs de graphe et des modificateurs de solution (solution modifiers) de SPARQL.

L'annexe A contient la définition normative de la syntaxe du langage d'interrogation SPARQL, selon une grammaire exprimée en notation EBNF.

1.2 Conventions du document

1.2.1 Espaces de noms

Dans ce document, les exemples supposent les liaisons de préfixe d'espace de noms suivantes, sauf indication contraire :

Préfixe Adresse IRI
rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns#
rdfs: http://www.w3.org/2000/01/rdf-schema#
xsd: http://www.w3.org/2001/XMLSchema#
fn: http://www.w3.org/2005/xpath-functions#

1.2.2 Descriptions des données

Ce document emploie le format de données Turtle [TURTLE] pour montrer explicitement chaque triplet. Le format Turtle permet d'abréger les adresses IRI en préfixes :

@prefix dc:   <http://purl.org/dc/elements/1.1/> .
@prefix :     <http://example.org/book/> .
:book1  dc:title  "SPARQL Tutorial" .

1.2.3 Descriptions des résultats

Les ensembles de résultat (result sets) sont illustrés sous une forme tabulaire.

x y z
"Alice" <http://example/a>      

Une « liaison » (binding) est un couple de la forme (variableterme RDF). Dans cet ensemble de résultats, il y a trois variables : x, y et z (données en rubriques de colonne). Chaque solution apparaît comme une seule rangée dans le corps du tableau. Ici il y a une seule solution, où la variable x est liée à "Alice", la variable y est liée à <http://example/a> et la variable z n'est pas liée à un terme RDF. Les variables ne sont pas nécessairement liées dans une solution.

1.2.4 Terminologie

Le langage SPARQL inclut des adresses IRI, un sous-ensemble des références IRI de RDF qui omet les espaces. Notez que toutes les adresses IRI dans les interrogations SPARQL sont absolues ; elles peuvent ou non contenir un identificateur de fragment [RFC3987, section 3.1]. Les adresses IRI incluent les adresses URI [RFC3986] et les adresses URL. Les formes abrégées (adresses IRI relatives et noms préfixés) dans la syntaxe SPARQL se résolvent en adresses IRI absolues.

Les termes suivants, définis dans Concepts et syntaxe abstraite RDF [CONCEPTS], sont employés dans SPARQL :

2 Effectuer des interrogations simples (informatif)

La plupart des formes d'interrogation SPARQL contiennent un ensemble de motifs de triplet (triple patterns) appelé un motif de graphe élémentaire (basic graph pattern). Les motifs de triplet sont comme les triplets RDF sauf que chaque sujet, prédicat et objet peut être une variable. Un motif de graphe élémentaire correspond à un sous-graphe des données RDF lorsque les termes RDF (RDF terms) de ce sous-graphe peuvent être substitués par les variables et que le résultat est un graphe RDF équivalent au sous-graphe.

2.1 Écrire une interrogation simple

L'exemple ci-dessous montre une interrogation SPARQL pour trouver le titre d'un livre dans le graphe de données fourni. L'interrogation comprend deux parties : la clause SELECT identifie les variables qui doivent apparaître dans les résultats d'interrogation (query results), et la clause WHERE fournit le motif de graphe élémentaire auquel comparer (match against) le graphe de données. Le motif de graphe élémentaire dans cet exemple se compose d'un seul motif de triplet avec une seule variable (?title) en position d'objet.

Données :

<http://example.org/book/book1> <http://purl.org/dc/elements/1.1/title> "SPARQL Tutorial" .

Interrogation :

SELECT ?title
WHERE
{
  <http://example.org/book/book1> <http://purl.org/dc/elements/1.1/title> ?title .
}    

Cette interrogation effectuée sur les données ci-dessus a une seule solution :

Résultat d'interrogation :

title
"SPARQL Tutorial"

2.2 Correspondances multiples

Le résultat d'une interrogation est une séquence de solutions, correspondant aux façons dont le motif de graphe de l'interrogation filtre les données. Il peut y avoir zéro, une ou plusieurs solutions à une interrogation.

Données :

@prefix foaf:  <http://xmlns.com/foaf/0.1/> .

_:a  foaf:name   "Johnny Lee Outlaw" .
_:a  foaf:mbox   <mailto:jlow@example.com> .
_:b  foaf:name   "Peter Goodguy" .
_:b  foaf:mbox   <mailto:peter@example.org> .
_:c  foaf:mbox   <mailto:carol@example.org> .

Interrogation :

PREFIX foaf:   <http://xmlns.com/foaf/0.1/>
SELECT ?name ?mbox
WHERE
  { ?x foaf:name ?name .
    ?x foaf:mbox ?mbox }

Résultat d'interrogation :

name mbox
"Johnny Lee Outlaw" <mailto:jlow@example.com>
"Peter Goodguy" <mailto:peter@example.org>

Chaque solution représente une façon de lier les variables sélectionnées aux termes RDF pour que le motif d'interrogation corresponde aux données. L'ensemble de résultats donne toutes les solutions possibles. Dans l'exemple ci-dessus, les deux correspondances ont été fournies par les deux sous-ensembles de données suivants :

 _:a foaf:name  "Johnny Lee Outlaw" .
 _:a foaf:box   <mailto:jlow@example.com> .
 _:b foaf:name  "Peter Goodguy" .
 _:b foaf:box   <mailto:peter@example.org> .

Il s'agit d'un filtrage de motif de graphe élémentaire ; toutes les variables utilisées dans le motif d'interrogation doivent être liées dans toutes les solutions.

2.3 Filtrage des littéraux RDF

Les données suivantes contiennent trois littéraux RDF :

@prefix dt:   <http://example.org/datatype#> .
@prefix ns:   <http://example.org/ns#> .
@prefix :     <http://example.org/ns#> .
@prefix xsd:  <http://www.w3.org/2001/XMLSchema#> .

:x   ns:p     "cat"@en .
:y   ns:p     "42"^^xsd:integer .
:z   ns:p     "abc"^^dt:specialDatatype .

En Turtle, notez que "cat"@en est un littéral RDF avec une forme lexicale "cat" et une langue en ; "42"^^xsd:integer est un littéral typé ayant le type de données http://www.w3.org/2001/XMLSchema#integer ; et "abc"^^dt:specialDatatype est un littéral typé ayant le type de données http://example.org/datatype#specialDatatype.

Ces données RDF constituent le graphe de données pour les exemples d'interrogations aux sections 2.3.1 à 2.3.3.

2.3.1 Filtrage des littéraux avec une étiquette de langue

Dans SPARQL, les étiquettes de langue s'expriment en utilisant le caractère @ et l'étiquette de langue, comme définie dans les Pratiques exemplaires 47 [BCP47].

L'interrogation suivante n'a aucune solution parce que "cat" n'est pas le même littéral que "cat"@en :

SELECT ?v WHERE { ?v ?p "cat" }
   v    

Tandis que l'interrogation suivante produira une solution où la variable v est liée à :x parce que l'étiquette de langue est indiquée et correspond aux données fournies :

SELECT ?v WHERE { ?v ?p "cat"@en }
v
<http://example.org/ns#x>

2.3.2 Filtrage des littéraux avec un type numérique

Dans une interrogation SPARQL, les entiers indiquent un littéral typé RDF avec le type de données xsd:integer. Par exemple, 42 est une forme abrégée de "42"^^<http://www.w3.org/2001/XMLSchema#integer>.

Le motif dans l'interrogation suivante a une solution avec la variable v liée à :y.

SELECT ?v WHERE { ?v ?p 42 }
v
<http://example.org/ns#y>

La section 4.1.2 définit les formes abrégées SPARQL pour les types xsd:float et xsd:double.

2.3.3 Filtrage des littéraux avec un type de données arbitraire

L'interrogation suivante a une solution avec la variable v liée à :z. Le processeur d'interrogation (query processor) n'a pas besoin d'avoir une connaissance des valeurs dans l'espace du type de données. Parce que la forme lexicale et l'adresse IRI de type de données sont toutes deux correspondantes, le littéral correspond.

SELECT ?v WHERE { ?v ?p "abc"^^<http://example.org/datatype#specialDatatype> }
v
<http://example.org/ns#z>

2.4 Étiquettes de nœud anonyme dans les résultats d'interrogation

Les résultats d'interrogation peuvent contenir des nœuds anonymes (blank nodes). Les nœuds anonymes dans les exemples d'ensembles de résultats dans ce document s'écrivent sous la forme d'une chaîne "_:" suivie d'une étiquette de nœud anonyme (blank node label).

Les étiquettes de nœud anonyme s'appliquent dans la portée d'un ensemble de résultats (comme défini dans la spécification Format XML des résultats d'interrogation SPARQL) ou, pour la forme d'interrogation CONSTRUCT, du graphe résultat. L'utilisation de la même étiquette à l'intérieur d'un ensemble de résultats indique le même nœud anonyme.

Données :
@prefix foaf:  <http://xmlns.com/foaf/0.1/> .

_:a  foaf:name   "Alice" .
_:b  foaf:name   "Bob" .
Interrogation :
PREFIX foaf:   <http://xmlns.com/foaf/0.1/>
SELECT ?x ?name
WHERE  { ?x foaf:name ?name }
x name
_:c "Alice"
_:d "Bob"

Les résultats ci-dessus pourraient tout aussi bien être donnés en utilisant des étiquettes de nœud anonyme différentes, car les étiquettes dans les résultats indiquent seulement si les termes RDF dans les solutions sont les mêmes ou sont différents.

x name
_:r "Alice"
_:s "Bob"

Ces deux résultats donnent les mêmes informations : les nœuds anonymes utilisés pour correspondre à l'interrogation sont différents dans les deux solutions. Il n'est pas nécessaire qu'il y ait une relation entre une étiquette _:a dans l'ensemble de résultats et un nœud anonyme dans le graphe de données avec la même étiquette.

Un auteur d'applications ne devrait pas supposer que les étiquettes de nœud anonyme dans une interrogation se rapportent à un nœud anonyme particulier dans les données.

2.5 Construction des graphes RDF

SPARQL offre plusieurs formes d'interrogation. La forme d'interrogation SELECT retourne des liaisons de variables. La forme d'interrogation CONSTRUCT retourne un graphe RDF. Le graphe est construit d'après un gabarit (template) utilisé pour générer des triplets RDF en fonction des résultats concordant avec le motif de graphe de l'interrogation.

Données :

@prefix org:    <http://example.com/ns#> .

_:a  org:employeeName   "Alice" .
_:a  org:employeeId     12345 .

_:b  org:employeeName   "Bob" .
_:b  org:employeeId     67890 .

Interrogation :

PREFIX foaf:   <http://xmlns.com/foaf/0.1/>
PREFIX org:    <http://example.com/ns#>

CONSTRUCT { ?x foaf:name ?name }
WHERE  { ?x org:employeeName ?name }

Résultat :

@prefix org: <http://example.com/ns#> .
      
_:x foaf:name "Alice" .
_:y foaf:name "Bob" .

que l'on peut sérialiser en RDF/XML ainsi :

<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:foaf="http://xmlns.com/foaf/0.1/"
    >
  <rdf:Description>
    <foaf:name>Alice</foaf:name>
  </rdf:Description>
  <rdf:Description>
    <foaf:name>Bob</foaf:name>
  </rdf:Description>
</rdf:RDF>

3 Contraintes des termes RDF (informatif)

Le filtrage du motif de graphe produit une séquence de solutions, où chaque solution est constituée par un ensemble de liaisons de variables à des termes RDF. Les clauses FILTER SPARQL restreignent les solutions à celles que l'expression de filtre évalue à true.

Cette section est une introduction informelle aux filtres SPARQL ; leurs sémantiques sont définies à la section 11. Test des valeurs. Les exemples de cette section partagent le graphe d'entrée suivant :

Données :
@prefix dc:   <http://purl.org/dc/elements/1.1/> .
@prefix :     <http://example.org/book/> .
@prefix ns:   <http://example.org/ns#> .

:book1  dc:title  "SPARQL Tutorial" .
:book1  ns:price  42 .
:book2  dc:title  "The Semantic Web" .
:book2  ns:price  23 .

3.1 Restriction de la valeur des chaînes

Les fonctions de filtre (FILTER) SPARQL comme regex peuvent tester les littéraux RDF. La fonction regex filtre seulement les littéraux ordinaires sans étiquette de langue. On peut utiliser regex pour filtrer les formes lexicales d'autres littéraux avec la fonction str.

Interrogation :

PREFIX  dc:  <http://purl.org/dc/elements/1.1/>
SELECT  ?title
WHERE   { ?x dc:title ?title
          FILTER regex(?title, "^SPARQL") 
        }

Résultat d'interrogation :

title
"SPARQL Tutorial"

Le filtrage par les expressions rationnelles (regular expression) peut être indépendant de la casse en utilisant le drapeau "i".

Interrogation :

PREFIX  dc:  <http://purl.org/dc/elements/1.1/>
SELECT  ?title
WHERE   { ?x dc:title ?title
          FILTER regex(?title, "web", "i" ) 
        }

Résultat d'interrogation :

title
"The Semantic Web"

Le langage d'expression rationnelle est défini par la spécification Fonctions et opérateurs de XQuery 1.0 et XPath 2.0 et repose sur les expressions rationnelles de XML Schema.

3.2 Restriction des valeurs numériques

Les clauses FILTER SPARQL peuvent restreindre les expressions arithmétiques.

Interrogation :

PREFIX  dc:  <http://purl.org/dc/elements/1.1/>
PREFIX  ns:  <http://example.org/ns#>
SELECT  ?title ?price
WHERE   { ?x ns:price ?price .
          FILTER (?price < 30.5)
          ?x dc:title ?title . }

Résultat d'interrogation :

title price
"The Semantic Web" 23

En contraignant la variable price, seul :book2 répond à l'interrogation, puisque seul à avoir un prix inférieur à 30.5, comme l'impose la condition de filtre.

3.3 Autres contraintes de termes

Outre les types numériques, SPARQL intègre les types xsd:string, xsd:boolean et xsd:dateTime (cf. la section 11.1 Types de données des opérandes). La section 11.3 Conversion des opérateurs liste un jeu de fonctions de test, dont BOUND, isLITERAL et langMATCHES, et d'accesseurs (accessors), dont STR, LANG et DATATYPE. La section 11.5 Fonctions constructrices liste un jeu de fonctions constructrices XML Schema intégrées au langage SPARQL pour le transtypage (cast) des valeurs.

4 Syntaxe SPARQL

Cette section couvre la syntaxe utilisée par SPARQL pour les termes RDF et les motifs de triplet. La grammaire complète est donnée à l'annexe A.

4.1 Syntaxe des termes RDF

4.1.1 Syntaxe des adresses IRI

La production IRIref désigne l'ensemble des adresses IRI [RFC3987] ; les adresses IRI constituent une généralisation des adresses URI [RFC3986] et sont entièrement compatibles avec les adresses URI et URL. La production PrefixedName désigne un nom préfixé. La correspondance d'un nom préfixé à une adresse IRI est décrite ci-dessous. Les références IRI (des adresses IRI relatives ou absolues) sont désignées par la production IRI_REF, où les caractères délimiteurs « < » et « > » ne font pas partie des références IRI. Les adresses IRI relatives correspondent aux références irelative-ref à la section 2.2 Définition ABNF des références IRI et des adresses IRI dans [RFC3987] et se résolvent en adresses IRI comme décrit ci-dessous.

Règles de grammaire :
[67]   IRIref   ::=   IRI_REF | PrefixedName
[68]   PrefixedName   ::=   PNAME_LN | PNAME_NS
[69]   BlankNode   ::=   BLANK_NODE_LABEL | ANON
[70]   IRI_REF   ::=   '<' ([^<>"{}|^`\]-[#x00-#x20])* '>'
[71]   PNAME_NS   ::=   PN_PREFIX? ':'
[72]   PNAME_LN   ::=   PNAME_NS PN_LOCAL

L'ensemble des termes RDF définis dans la spécification Concepts et syntaxe abstraite RDF comprend des références URI RDF tandis que les termes SPARQL contiennent des adresses IRI. Les références URI RDF contenant des caractères « < », « > », « " », ESPACE, « { », « } », « | », « \ », « ^ » et « ` » ne sont pas des adresses IRI. Le comportement d'une interrogation SPARQL contre des déclarations RDF composées de telles références URI RDF n'est pas défini.

Noms préfixés

Le mot-clé PREFIX associe une étiquette de préfixe à une adresse IRI. Un nom préfixé se compose d'une étiquette de préfixe et d'une partie locale, séparés par un caractères DEUX-POINTS « : ». Un nom préfixé est converti (mapped) en une adresse IRI en concaténant l'addresse IRI associée au préfixe et la partie locale. L'étiquette de préfixe ou la partie locale peuvent être vides. Notez que les noms locaux SPARQL admettent les chiffres en tête, contrairement aux noms locaux XML.

Adresses IRI relatives

Les adresses IRI relatives sont combinées aux adresses IRI de base conformément au RFC Identificateur de ressource uniforme (URI) — Syntaxe générique [RFC3986] en n'utilisant que l'algorithme de base de la section 5.2. Ni la normalisation fondée sur la syntaxe ni la normalisation fondée sur un schéma (décrites aux sections 6.2.2 et 6.2.3 du RFC 3986) ne sont réalisées. Les caractères admis en plus dans les références IRI sont traités de la même façon que le sont les caractères non réservés dans les références URI, selon la section 6.5 du RFC Identificateurs de ressource internationalisés (IRI) [RFC3987].

Le mot-clé BASE définit l'adresse IRI de base utilisée pour résoudre les adresses IRI relatives, selon la section 5.1.1 Adresse URI de base incorporée au contenu du RFC 3986. La section 5.1.2 Adresse URI de base de l'entité encapsulante définit comment l'adresse IRI de base peut provenir d'un document encapsulant, tel qu'une enveloppe SOAP avec une directive xml:base, ou un document MIME de type multipart avec un en-tête Content-Location. L'« adresse URI de récupération » (Retrieval URI), identifiée à la section 5.1.3 Adresse URI de base de l'adresse URI de récupération, est l'adresse URL depuis laquelle une interrogation SPARQL particulière est récupérée. Si aucune des méthodes précédentes ne définit l'adresse URI de base, c'est l'adresse URI de base par défaut (cf. la section 5.1.4 Adresse URI de base par défaut) qui est utilisée.

Les fragments suivants représentent quelques unes des différentes façons d'écrire la même adresse IRI :

<http://example.org/book/book1>
BASE <http://example.org/book/>
<book1>
PREFIX book: <http://example.org/book/>
book:book1

4.1.2 Syntaxe des littéraux

La syntaxe générale des littéraux est une chaîne (entre des guillemets doubles, "...", ou bien simples, '...'), avec soit une étiquette de langue optionnelle (introduite par un caractère « @ »), soit une adresse IRI de type de données ou un nom préfixé optionnels (introduits par ^^).

Par commodité, les entiers peuvent être écrits directement (sans guillemets ni adresse IRI de type de données explicite) et sont interprétés comme des littéraux typés de type xsd:integer ; les nombres décimaux dans lesquels il y a un caractère « . » mais pas d'exposant sont interprétés comme des type xsd:decimal ; les nombres avec des exposants sont interprétés comme des types xsd:double. Les valeurs de type xsd:boolean peuvent aussi s'écrire true ou false.

Pour faciliter l'écriture des valeurs littérales contenant elles-mêmes des guillemets, ou longues et comprenant des caractères CHANGEMENT DE LIGNE, SPARQL fournit une structure de citation supplémentaire dans laquelle les littéraux sont englobés par des guillemets doubles ou simples triples.

Voici des exemples de syntaxe littérale dans SPARQL :

Règles de grammaire :
[60]   RDFLiteral   ::=   String ( LANGTAG | ( '^^' IRIref ) )?
[61]   NumericLiteral   ::=   NumericLiteralUnsigned |
NumericLiteralPositive |
NumericLiteralNegative
[62]   NumericLiteralUnsigned   ::=   INTEGER | DECIMAL | DOUBLE
[63]   NumericLiteralPositive   ::=   INTEGER_POSITIVE |
DECIMAL_POSITIVE |
DOUBLE_POSITIVE
[64]   NumericLiteralNegative   ::=   INTEGER_NEGATIVE |
DECIMAL_NEGATIVE |
DOUBLE_NEGATIVE
[65]   BooleanLiteral   ::=   'true' | 'false'
[66]   String   ::=   STRING_LITERAL1 | STRING_LITERAL2 |
STRING_LITERAL_LONG1 | STRING_LITERAL_LONG2
[76]   LANGTAG   ::=   '@' [a-zA-Z]+ ('-' [a-zA-Z0-9]+)*
[77]   INTEGER   ::=   [0-9]+
[78]   DECIMAL   ::=   [0-9]+ '.' [0-9]* | '.' [0-9]+
[79]   DOUBLE   ::=   [0-9]+ '.' [0-9]* EXPONENT |
'.' ([0-9])+ EXPONENT |
([0-9])+ EXPONENT
[80]   INTEGER_POSITIVE   ::=   '+' INTEGER
[81]   DECIMAL_POSITIVE   ::=   '+' DECIMAL
[82]   DOUBLE_POSITIVE   ::=   '+' DOUBLE
[83]   INTEGER_NEGATIVE   ::=   '-' INTEGER
[84]   DECIMAL_NEGATIVE   ::=   '-' DECIMAL
[85]   DOUBLE_NEGATIVE   ::=   '-' DOUBLE
[86]   EXPONENT   ::=   [eE] [+-]? [0-9]+
[87]   STRING_LITERAL1   ::=   "'" ( ([^#x27#x5C#xA#xD]) | ECHAR )* "'"
[88]   STRING_LITERAL2   ::=   '"' ( ([^#x22#x5C#xA#xD]) | ECHAR )* '"'

Les atomes (tokens) correspondant aux productions INTEGER, DECIMAL, DOUBLE et BooleanLiteral équivalent à un littéral typé avec la valeur lexicale de l'atome et le type de données associé (xsd:integer, xsd:decimal, xsd:double, xsd:boolean).

4.1.3 Syntaxe des variables d'interrogation

Les variables d'interrogation (query variables) dans les interrogations SPARQL ont une portée globale (global scope) ; l'utilisation d'un nom de variable donné partout dans une interrogation identifie la même variable. Les variables sont préfixées soit par un caractère « ? », soit par un caractère « $ » ; les caractères « ? » et « $ » ne font pas partie du nom de la variable. Dans une interrogation, $abc et ?abc identifient la même variable. Les noms possibles des variables sont donnés dans la grammaire SPARQL.

Règles de grammaire :
[44] Var   ::=   VAR1 | VAR2
[74]   VAR1   ::=   '?' VARNAME
[75]   VAR2   ::=   '$' VARNAME
[97]   VARNAME   ::=   ( PN_CHARS_U | [0-9] ) ( PN_CHARS_U | [0-9] | #x00B7 | [#x0300-#x036F] | [#x203F-#x2040] )*

4.1.4 Syntaxe des nœuds anonymes

Les nœuds anonymes dans les motifs de graphe agissent comme des variables indistinctes, non comme des références à des nœuds anonymes spécifiques dans les données interrogées.

Les nœuds anonymes sont indiqués soit sous forme d'une étiquette, telle que "_:abc", soit sous la forme abrégée "[]". Un nœud anonyme utilisé seulement à une place dans la syntaxe d'interrogation peut être indiqué avec []. Un nœud anonyme unique sera utilisé pour former le motif de triplet. Les étiquettes de nœud anonyme s'écrivent ainsi : "_:abc" pour un nœud anonyme avec l'étiquette "abc". Le même nœud anonyme ne peut pas être utilisé dans deux motifs de graphe élémentaires différents dans la même interrogation.

La structure [:p :v] peut être utilisée dans les motifs de triplet. Elle crée une étiquette de nœud anonyme qui sert de sujet à tous les couples prédicat-objet contenus. Le nœud anonyme créé peut aussi être utilisé dans d'autres motifs de triplet en position de sujet et d'objet.

Les deux formes suivantes :

[ :p "v" ] .
[] :p "v" .

allouent une étiquette de nœud anonyme unique (ici "b57") et sont équivalentes à l'écriture suivante :

_:b57 :p "v" .

Cette étiquette de nœud anonyme allouée peut être utilisée comme sujet ou objet d'autres motifs de triplet. Par exemple, comme sujet :

[ :p "v" ] :q "w" .

ce qui équivaut aux deux triplets suivants :

_:b57 :p "v" .
_:b57 :q "w" .

et comme objet :

:x :q [ :p "v" ] .

ce qui équivaut aux deux triplets :

:x  :q _:b57 .
_:b57 :p "v" .

On peut combiner la syntaxe de nœud anonyme abrégée avec d'autres abréviations pour des sujets communs et des prédicats communs.

  [ foaf:name  ?name ;
    foaf:mbox  <mailto:alice@example.org> ]

C'est la même chose que d'écrire le motif de graphe élémentaire suivant pour une étiquette de nœud anonyme allouée exclusivement, "b18" :

  _:b18  foaf:name  ?name .
  _:b18  foaf:mbox  <mailto:alice@example.org> .
Règles de grammaire :
[39]   BlankNodePropertyList   ::=   '['PropertyListNotEmpty']'
[69]   BlankNode   ::=   BLANK_NODE_LABEL | ANON
[73]   BLANK_NODE_LABEL   ::=   '_:' PN_LOCAL
[94]   ANON   ::=   '[' WS* ']'

4.2 Syntaxe des motifs de triplet

Les motifs de triplet se présentent comme une liste formée d'un sujet, d'un prédicat et d'un objet, séparés par des caractères blancs ; il existe des façons abrégées d'écrire quelques structures de motif de triplet courantes.

Les exemples suivants expriment la même interrogation :

PREFIX  dc: <http://purl.org/dc/elements/1.1/>
SELECT  ?title
WHERE   { <http://example.org/book/book1> dc:title ?title }  
PREFIX  dc: <http://purl.org/dc/elements/1.1/>
PREFIX  : <http://example.org/book/>

SELECT  $title
WHERE   { :book1  dc:title  $title }
BASE    <http://example.org/book/>
PREFIX  dc: <http://purl.org/dc/elements/1.1/>

SELECT  $title
WHERE   { <book1>  dc:title  ?title }
Règles de grammaire :
[32]   TriplesSameSubject   ::=   VarOrTerm PropertyListNotEmpty |
TriplesNode PropertyList
[33]   PropertyListNotEmpty   ::=   Verb ObjectList ( ';' ( Verb ObjectList )? )*
[34]   PropertyList   ::=   PropertyListNotEmpty?
[35]   ObjectList   ::=   Object ( ',' Object )*
[37]   Verb   ::=   VarOrIRIref | 'a'

4.2.1 Listes de prédicats et d'objets

On peut écrire des motifs de triplet dont le sujet est commun, le sujet est donc écrit une seule fois et utilisé pour plusieurs motifs de triplet en utilisant le caractère POINT-VIRGULE « ; ».

    ?x  foaf:name  ?name ;
        foaf:mbox  ?mbox .

C'est la même chose que d'écrire les motifs de triplet suivants :

    ?x  foaf:name  ?name .
    ?x  foaf:mbox  ?mbox .

4.2.2 Listes d'objets

Si des motifs de triplet partagent à la fois un sujet et un prédicat, les objets peuvent être séparés par un caractère VIRGULE « , ».

    ?x foaf:nick  "Alice" , "Alice_" .

C'est la même chose que d'écrire les motifs de triplet suivants :

   ?x  foaf:nick  "Alice" .
   ?x  foaf:nick  "Alice_" .

On peut combiner des listes d'objets et des listes de prédicats et d'objets :

   ?x  foaf:name ?name ; foaf:nick  "Alice" , "Alice_" .

Cela équivaut à :

   ?x  foaf:name  ?name .
   ?x  foaf:nick  "Alice" .
   ?x  foaf:nick  "Alice_" .

4.2.3 Collections RDF

Les collections RDF peuvent s'écrire comme des motifs de triplet en utilisant la syntaxe "(élément1 élément2 ...)". La forme "()" est une alternative pour l'adresse IRI http://www.w3.org/1999/02/22-rdf-syntax-ns#nil. Lorsqu'on l'utilise avec les éléments d'une collection, telle que (1 ?x 3 4), des motifs de triplet avec des nœuds anonymes sont alloués à la collection. Le nœud anonyme en tête de la collection peut être utilisé comme sujet ou objet dans d'autres motifs de triplet. Les nœuds anonymes alloués par la syntaxe de la collection n'apparaissent pas ailleurs dans l'interrogation.

(1 ?x 3 4) :p "w" .

Est un sucre syntaxique pour (en remarquant que b0, b1, b2 et b3 n'apparaissent pas ailleurs dans l'interrogation) :

    _:b0  rdf:first  1 ;
          rdf:rest   _:b1 .
    _:b1  rdf:first  ?x ;
          rdf:rest   _:b2 .
    _:b2  rdf:first  3 ;
          rdf:rest   _:b3 .
    _:b3  rdf:first  4 ;
          rdf:rest   rdf:nil .
    _:b0  :p         "w" . 

Les collections RDF peuvent être imbriquées et impliquer d'autres formes syntaxiques :

(1 [:p :q] ( 2 ) ) .

Est un sucre syntaxique pour :

    _:b0  rdf:first  1 ;
          rdf:rest   _:b1 .
    _:b1  rdf:first  _:b2 .
    _:b2  :p         :q .
    _:b1  rdf:rest   _:b3 .
    _:b3  rdf:first  _:b4 .
    _:b4  rdf:first  2 ;
          rdf:rest   rdf:nil .
    _:b3  rdf:rest   rdf:nil .
Règles de grammaire :
[40]   Collection   ::=   '(' GraphNode+ ')'
[92]   NIL   ::=   '(' WS* ')'

4.2.4 rdf:type

On peut utiliser le mot-clé "a" comme prédicat dans un motif de triplet ; c'est une alternative pour l'adresse IRI http://www.w3.org/1999/02/22-rdf-syntax-ns#type. Ce mot-clé est sensible à la casse.

  ?x  a  :Class1 .
  [ a :appClass ] :p "v" .

Est un sucre syntaxique pour :

  ?x    rdf:type  :Class1 .
  _:b0  rdf:type  :appClass .
  _:b0  :p        "v" .

5 Motifs de graphe

SPARQL repose sur la correspondance des motifs de graphe (graph patterns). On peut réaliser des motifs de graphe plus complexes en combinant des motifs plus petits de façons diverses :

Dans cette section, nous décrivons les deux types combinant les motifs par conjonction : les motifs de graphe élémentaires, qui combinent les motifs de triplet, et les motifs de graphe de groupe, qui combinent tous les autres motifs de graphe.

Le motif de graphe le plus externe dans une interrogation est appelé le motif d'interrogation (query pattern). Grammaticalement, il est identifié ci-dessous par GroupGraphPattern :

[13]   WhereClause   ::=   'WHERE'? GroupGraphPattern

5.1 Motifs de graphe élémentaires

Les motifs de graphe élémentaires sont des ensembles de motifs de triplet. Le filtrage par motif de graphe SPARQL est défini par la combinaison des résultats issus de la comparaison de motifs de graphe élémentaires.

Une suite de motifs de triplet interrompue par un filtre compose un seul motif de graphe élémentaire. Tout motif de graphe clôt un motif de graphe élémentaire.

5.1.1 Étiquettes de nœud anonyme

Lorsqu'on utilise des nœuds anonymes de la forme _:abc, la portée des étiquettes des nœuds anonymes est limitée au motif de graphe élémentaire. On ne peut utiliser une étiquette que dans un seul motif de graphe élémentaire dans une interrogation.

5.1.2 Extension du filtrage des motifs de graphe élémentaires

SPARQL est défini pour filtrer des graphes RDF à inférence simple (simple entailment). On peut étendre SPARQL à d'autres formes d'inférence sous certaines conditions, comme décrites ci-dessous.

5.2 Motifs de graphe de groupe

Dans une chaîne d'interrogation (query string) SPARQL, un motif de graphe de groupe est délimité par des accolades : {}. Par exemple, le motif d'interrogation de l'interrogation suivante est un motif de graphe de groupe comprenant un seul motif de graphe élémentaire :

PREFIX foaf:    <http://xmlns.com/foaf/0.1/>
SELECT ?name ?mbox
WHERE  {
          ?x foaf:name ?name .
          ?x foaf:mbox ?mbox .
       }
On obtiendrait les mêmes solutions à partir d'une interrogation qui aurait regroupé les motifs de triplet en deux motifs de graphe élémentaires. Ainsi, l'interrogation ci-dessous a une structure différente mais elle produirait les mêmes solutions que l'interrogation précédente :
PREFIX foaf:    <http://xmlns.com/foaf/0.1/>
SELECT ?name ?mbox
WHERE  { { ?x foaf:name ?name . }
         { ?x foaf:mbox ?mbox . }
       }
Règles de grammaire :
[20]   GroupGraphPattern   ::=   '{' TriplesBlock? ( ( GraphPatternNotTriples | Filter ) '.'? TriplesBlock? )* '}'
[21]   TriplesBlock   ::=   TriplesSameSubject ( '.' TriplesBlock? )?
[22]   GraphPatternNotTriples   ::=   OptionalGraphPattern | GroupOrUnionGraphPattern | GraphGraphPattern

5.2.1 Motif de groupe vide

Le motif de groupe :

{ }

filtre tout graphe (y compris le graphe vide) avec une solution qui ne lie pas de variables. Par exemple :

SELECT ?x
WHERE {}

correspond à une solution dans laquelle la variable x n'est pas liée.

5.2.2 Portée des filtres

Une contrainte, exprimée par le mot-clé FILTER, est une restriction des solutions sur tout le groupe où le filtre apparaît. Toutes les formes suivantes ont les mêmes solutions :

 {  ?x foaf:name ?name .
    ?x foaf:mbox ?mbox .
    FILTER regex(?name, "Smith")
 }
 {  FILTER regex(?name, "Smith")
    ?x foaf:name ?name .
    ?x foaf:mbox ?mbox .
 }
 {  ?x foaf:name ?name .
    FILTER regex(?name, "Smith")
    ?x foaf:mbox ?mbox .
 }

5.2.3 Exemples de motifs de graphe de groupe

Ce groupe comprend un seul motif de graphe élémentaire ; ce motif de graphe élémentaire est composé de deux motifs de triplet :

  {
    ?x foaf:name ?name .
    ?x foaf:mbox ?mbox .
  }

Ce groupe comprend un seul motif de graphe élémentaire et un filtre ; ce motif de graphe élémentaire est composé de deux motifs de triplet ; le filtre ne rompt pas le motif de graphe élémentaire en deux motifs de graphe élémentaires :

  {
    ?x foaf:name ?name . FILTER regex(?name, "Smith")
    ?x foaf:mbox ?mbox .
  }

Ce groupe comprend trois éléments : un motif de graphe élémentaire composé d'un seul motif de triplet, un groupe vide et un autre motif de graphe élémentaire composé d'un seul motif de triplet :

  {
    ?x foaf:name ?name .
    {}
    ?x foaf:mbox ?mbox .
  }

6 Inclusion de valeurs optionnelles

Les motifs de graphe élémentaires permettent aux applications d'effectuer des interrogations où le motif d'interrogation entier doit correspondre pour qu'il y ait une solution. Pour chaque solution d'une interrogation contenant seulement des motifs de graphe de groupe avec au moins un motif de graphe élémentaire, chaque variable est liée à un terme RDF dans une solution. Toutefois, on ne peut pas supposer la présence de structures complètes et régulières dans tous les graphes RDF. Il est utile d'avoir des interrogations qui puissent ajouter des informations à la solution où l'information est disponible, mais qui ne rejettent pas la solution parce que des parties du motif d'interrogation ne correspondent pas. Cette fonction est offerte par le filtrage optionnel (optional matching) : si la partie optionnelle ne correspond pas, elle ne crée aucune liaison mais n'élimine pas la solution.

6.1 Filtrage par motif optionnel

On peut définir syntaxiquement des parties optionnelles dans le motif de graphe en appliquant le mot-clé OPTIONAL au motif de graphe :

motif OPTIONAL { motif }

Cette forme syntaxique :

{ OPTIONAL { motif } }

équivaut à la suivante :

{ { } OPTIONAL { motif } }
Règle de grammaire :
[23]   OptionalGraphPattern   ::=   'OPTIONAL' GroupGraphPattern

Le mot-clé OPTIONAL est associatif à gauche (left-associative) :

motif OPTIONAL { motif } OPTIONAL { motif }

est la même chose que :

{ motif OPTIONAL { motif } } OPTIONAL { motif }

Dans un filtrage optionnel, soit le motif de graphe optionnel correspond à un graphe, en définissant et ajoutant ainsi des liaisons à une ou plusieurs solutions, soit il laisse une solution inchangée sans ajouter de liaisons supplémentaires.

Données :

@prefix foaf:       <http://xmlns.com/foaf/0.1/> .
@prefix rdf:        <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .

_:a  rdf:type        foaf:Person .
_:a  foaf:name       "Alice" .
_:a  foaf:mbox       <mailto:alice@example.com> .
_:a  foaf:mbox       <mailto:alice@work.example> .

_:b  rdf:type        foaf:Person .
_:b  foaf:name       "Bob" .
Interrogation :
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name ?mbox
WHERE  { ?x foaf:name  ?name .
         OPTIONAL { ?x  foaf:mbox  ?mbox }
       }

Avec les données précédentes, le résultat d'interrogation est :

name mbox
"Alice" <mailto:alice@example.com>
"Alice" <mailto:alice@work.example>
"Bob"

Il n'y a pas de valeur pour mbox dans la solution où le nom est "Bob".

Cette interrogation trouve les noms des personnes dans les données. S'il y a un triplet avec le prédicat mbox et le même sujet, une solution contiendra également ce triplet. Dans cet exemple, on ne donne qu'un seul motif de triplet dans la partie à filtrage optionnel de l'interrogation mais, en général, la partie optionnelle peut être un motif de graphe quelconque. Le motif de graphe optionnel doit correspondre entièrement pour affecter la solution d'interrogation.

6.2 Contraintes du filtrage par motif optionnel

On peut fournir des contraintes dans un motif de graphe optionnel. Par exemple :

@prefix dc:   <http://purl.org/dc/elements/1.1/> .
@prefix :     <http://example.org/book/> .
@prefix ns:   <http://example.org/ns#> .

:book1  dc:title  "SPARQL Tutorial" .
:book1  ns:price  42 .
:book2  dc:title  "The Semantic Web" .
:book2  ns:price  23 .
PREFIX  dc:  <http://purl.org/dc/elements/1.1/>
PREFIX  ns:  <http://example.org/ns#>
SELECT  ?title ?price
WHERE   { ?x dc:title ?title .
          OPTIONAL { ?x ns:price ?price . FILTER (?price < 30) }
        }
title price
"SPARQL Tutorial"
"The Semantic Web" 23

Le prix du livre intitulé "SPARQL Tutorial" n'apparaît pas parce que le motif de graphe optionnel ne conduisait pas à une solution impliquant la variable "price".

6.3 Motifs de graphe optionnels multiples

Les motifs de graphe sont définis récursivement. Un motif de graphe peut avoir zéro ou plus motifs de graphe optionnels, et toute partie d'un motif d'interrogation peut avoir une partie optionnelle. Dans cet exemple, il y a deux motifs de graphe optionnels.

Données :
@prefix foaf:       <http://xmlns.com/foaf/0.1/> .

_:a  foaf:name       "Alice" .
_:a  foaf:homepage   <http://work.example.org/alice/> .

_:b  foaf:name       "Bob" .
_:b  foaf:mbox       <mailto:bob@work.example> .
Interrogation :
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name ?mbox ?hpage
WHERE  { ?x foaf:name  ?name .
         OPTIONAL { ?x foaf:mbox ?mbox } .
         OPTIONAL { ?x foaf:homepage ?hpage }
       }

Résultat d'interrogation :

name mbox hpage
"Alice" <http://work.example.org/alice/>
"Bob" <mailto:bob@work.example>

7 Filtrage des alternatives

SPARQL fournit un moyen de combiner les motifs de graphe de telle sorte que l'un des motifs de graphe alternatifs peut correspondre. Si plusieurs alternatives correspondent, toutes les solutions de motifs possibles sont trouvées.

Les alternatives de motifs sont indiquées syntaxiquement par le mot-clé UNION.

Données :
@prefix dc10:  <http://purl.org/dc/elements/1.0/> .
@prefix dc11:  <http://purl.org/dc/elements/1.1/> .

_:a  dc10:title     "SPARQL Query Language Tutorial" .
_:a  dc10:creator   "Alice" .

_:b  dc11:title     "SPARQL Protocol Tutorial" .
_:b  dc11:creator   "Bob" .

_:c  dc10:title     "SPARQL" .
_:c  dc11:title     "SPARQL (updated)" .
Interrogation :
PREFIX dc10:  <http://purl.org/dc/elements/1.0/>
PREFIX dc11:  <http://purl.org/dc/elements/1.1/>

SELECT ?title
WHERE  { { ?book dc10:title  ?title } UNION { ?book dc11:title  ?title } }

Résultat d'interrogation :

title
"SPARQL Protocol Tutorial"
"SPARQL"
"SPARQL (updated)"
"SPARQL Query Language Tutorial"

Cette interrogation trouve les titres des livres dans les données, que le titre soit enregistré en utilisant des propriétés Dublin Core en version 1.0 ou en version 1.1. Pour déterminer exactement comment l'information a été enregistrée, l'interrogation pourrait utiliser des variables différentes pour les deux alternatives :

PREFIX dc10:  <http://purl.org/dc/elements/1.0/>
PREFIX dc11:  <http://purl.org/dc/elements/1.1/>

SELECT ?x ?y
WHERE  { { ?book dc10:title ?x } UNION { ?book dc11:title  ?y } }
x y
"SPARQL (updated)"
"SPARQL Protocol Tutorial"
"SPARQL"
"SPARQL Query Language Tutorial"

Cela retournera un résultat avec la variable x liée aux solutions du segment gauche de l'UNION, et la variable y liée aux solutions du segment droit. Si aucune partie de la forme UNION ne correspondait, alors le motif de graphe ne correspondrait pas.

La forme UNION combine les motifs de graphe ; chaque possibilité alternative peut contenir plusieurs motifs de triplet :

PREFIX dc10:  <http://purl.org/dc/elements/1.0/>
PREFIX dc11:  <http://purl.org/dc/elements/1.1/>

SELECT ?title ?author
WHERE  { { ?book dc10:title ?title .  ?book dc10:creator ?author }
         UNION
         { ?book dc11:title ?title .  ?book dc11:creator ?author }
       }
author title
"Alice" "SPARQL Protocol Tutorial"
"Bob" "SPARQL Query Language Tutorial"

Cette interrogation ne correspondra à un livre que si son titre et son prédicat d'auteur sont tous deux de la même version de Dublin Core.

Règle de grammaire :
[25]   GroupOrUnionGraphPattern   ::=   GroupGraphPattern
( 'UNION' GroupGraphPattern )*

8 Ensemble de données RDF

Le modèle de données RDF exprime l'information sous forme de graphes consistant en triplets avec un sujet, un prédicat et un objet. Beaucoup de magasins de données RDF contiennent plusieurs graphes RDF et des données d'enregistrement (record information) pour chaque graphe, permettant à une application d'effectuer des interrogations impliquant des informations issues de plusieurs graphes.

Une interrogation SPARQL est exécutée auprès d'un ensemble de données RDF (RDF Dataset) qui représente une collection de graphes. Un ensemble de données RDF comprend un graphe anonyme, le graphe par défaut, et zéro ou plus graphes nommés où chaque graphe nommé est identifié par une adresse IRI. Une interrogation SPARQL peut comparer des parties différentes du motif d'interrogation à des graphes différents, comme décrit à la section 8.3 Interrogation de l'ensemble de données.

Un ensemble de données RDF peut contenir zéro graphe nommé ; un ensemble de données RDF contient toujours un seul graphe par défaut. Une interrogation n'a pas besoin d'inclure un filtrage du graphe par défaut ; l'interrogation peut juste inclure un filtrage des graphes nommés.

Le graphe utilisé pour filtrer un motif de graphe élémentaire est le graphe actif (active graphe). Dans les sections précédentes, toutes les interrogations sont illustrées en exécution par rapport à un seul graphe, le graphe par défaut d'un ensemble de données RDF comme graphe actif. On utilise le mot-clé GRAPH pour établir l'un parmi tous les graphes nommés dans l'ensemble de données comme graphe actif pour une partie de l'interrogation.

8.1 Exemples d'ensembles de données RDF

La définition de l'ensemble de données RDF ne restreint pas les relations des graphes nommées et du graphe par défaut. L'information peut être répétée dans des graphes différents ; les relations entre les graphes peuvent être exposées. Deux arrangements sont utiles :

Exemple 1 :
# Graphe par défaut
@prefix dc: <http://purl.org/dc/elements/1.1/> .

<http://example.org/bob>    dc:publisher  "Bob" .
<http://example.org/alice>  dc:publisher  "Alice" .
# Graphe nommé : http://example.org/bob
@prefix foaf: <http://xmlns.com/foaf/0.1/> .

_:a foaf:name "Bob" .
_:a foaf:mbox <mailto:bob@oldcorp.example.org> .
# Graphe nommé : http://example.org/alice
@prefix foaf: <http://xmlns.com/foaf/0.1/> .

_:a foaf:name "Alice" .
_:a foaf:mbox <mailto:alice@work.example.org> .

Dans cet exemple, le graphe par défaut contient les noms des auteurs des deux graphes nommés. Ici les triplets dans les graphes nommés ne sont pas visibles dans le graphe par défaut.

Example 2 :

Les données RDF peuvent être combinées par la fusion RDF (RDF merge) des graphes [RDF-MT]. Un arrangement possible des graphes dans un ensemble de données RDF est de faire du graphe par défaut la fusion RDF de la totalité ou d'une partie des informations contenues dans les graphes nommés.

Dans l'exemple suivant, les graphes nommés contiennent les mêmes triplets qu'auparavant. L'ensemble de données RDF inclut une fusion RDF des graphes nommés dans le graphe par défaut, en rétiquetant les nœuds anonymes pour les garder distincts.

# Graphe par défaut
@prefix foaf: <http://xmlns.com/foaf/0.1/> .

_:x foaf:name "Bob" .
_:x foaf:mbox <mailto:bob@oldcorp.example.org> .

_:y foaf:name "Alice" .
_:y foaf:mbox <mailto:alice@work.example.org> .
# Graphe nommé : http://example.org/bob
@prefix foaf: <http://xmlns.com/foaf/0.1/> .

_:a foaf:name "Bob" .
_:a foaf:mbox <mailto:bob@oldcorp.example.org> .
# Graphe nommé : http://example.org/alice
@prefix foaf: <http://xmlns.com/foaf/0.1/> .

_:a foaf:name "Alice" .
_:a foaf:mbox <mailto:alice@work.example> .

Dans une fusion RDF, les nœuds anonymes dans le graphe fusionné ne sont pas partagés avec les nœuds anonymes des graphes à fusionner.

8.2 Définition des ensembles de données RDF

Une interrogation SPARQL peut indiquer l'ensemble de données à utiliser au filtrage en utilisant les clauses FROM et FROM NAMED pour décrire l'ensemble de données RDF. Si une interrogation comporte une telle description d'un ensemble de données, alors cet ensemble de données est utilisé à la place de tout ensemble de données que le service d'interrogation (query service) utiliserait si l'interrogation ne fournissait pas de description d'ensemble de données. L'ensemble de données RDF peut également être défini dans une requête de protocole SPARQL, auquel cas la description de protocole écrase (override) toute description dans l'interrogation même. Un service d'interrogation peut refuser une requête d'interrogation si la description d'ensemble de données lui est inacceptable.

Les mots-clés FROM et FROM NAMED permettent à une interrogation d'indiquer un ensemble de données RDF par référence ; ils indiquent que l'ensemble de données devrait inclure des graphes obtenus à partir de représentations des ressources identifiées par les adresses IRI données (à savoir la forme absolue des références IRI fournies). L'ensemble de données obtenu à partir d'un certain nombre de clauses FROM et FROM NAMED est :

S'il n'y a pas de clause FROM mais une ou plusieurs clauses FROM NAMED, alors l'ensemble de données comprend un graphe vide pour le graphe par défaut.

Règles de grammaire :
[9]   DatasetClause   ::=   'FROM' ( DefaultGraphClause | NamedGraphClause )
[10]   DefaultGraphClause   ::=   SourceSelector
[11]   NamedGraphClause   ::=   'NAMED' SourceSelector
[12]   SourceSelector   ::=   IRIref

8.2.1 Définition du graphe par défaut

Chaque clause FROM contient une adresse IRI indiquant un graphe à utiliser pour former le graphe par défaut. Cela n'installe pas le graphe comme graphe nommé.

Dans cet exemple, l'ensemble de données RDF contient un seul graphe par défaut et aucun graphe nommé :

# Graphe par défaut (stocké à http://example.org/foaf/aliceFoaf)
@prefix  foaf:  <http://xmlns.com/foaf/0.1/> .

_:a  foaf:name     "Alice" .
_:a  foaf:mbox     <mailto:alice@work.example> .
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT  ?name
FROM    <http://example.org/foaf/aliceFoaf>
WHERE   { ?x foaf:name ?name }
name
"Alice"

Si une interrogation présente plusieurs clauses FROM, en fournissant plusieurs adresses IRI pour indiquer le graphe par défaut, alors le graphe par défaut est fondé sur la fusion RDF des graphes obtenus des représentations des ressources identifiées par les adresses IRI en question.

8.2.2 Définition des graphes nommés

Une interrogation peut fournir les adresses IRI des graphes nommés dans l'ensemble de données RDF avec la clause FROM NAMED. Chaque adresse IRI est utilisée pour fournir un seul graphe nommé dans l'ensemble de données RDF. L'utilisation d'une même adresse IRI dans deux ou plus clauses FROM NAMED se traduit par l'apparition d'un seul graphe nommé avec cette adresse IRI dans l'ensemble de données.

# Graphe : http://example.org/bob
@prefix foaf: <http://xmlns.com/foaf/0.1/> .

_:a foaf:name "Bob" .
_:a foaf:mbox <mailto:bob@oldcorp.example.org> .
# Graphe : http://example.org/alice
@prefix foaf: <http://xmlns.com/foaf/0.1/> .

_:a foaf:name "Alice" .
_:a foaf:mbox <mailto:alice@work.example> .
...
FROM NAMED <http://example.org/alice>
FROM NAMED <http://example.org/bob>
...

La syntaxe FROM NAMED suggère que l'adresse IRI identifie le graphe correspondant, mais la relation entre une adresse IRI et un graphe dans un ensemble de données RDF est indirecte. L'adresse IRI identie une ressource et la ressource est représentée par un graphe (ou, plus précisément, par un document qui sérialise un graphe). Pour plus de détails, cf. [WEBARCH].

8.2.3 Combinaison de FROM et FROM NAMED

On peut utiliser la clause FROM et la clause FROM NAMED dans la même interrogation.

# Graphe par défaut (stocké à http://example.org/dft.ttl)
@prefix dc: <http://purl.org/dc/elements/1.1/> .

<http://example.org/bob>    dc:publisher  "Bob Hacker" .
<http://example.org/alice>  dc:publisher  "Alice Hacker" .
# Graphe nommé : http://example.org/bob
@prefix foaf: <http://xmlns.com/foaf/0.1/> .

_:a foaf:name "Bob" .
_:a foaf:mbox <mailto:bob@oldcorp.example.org> .
# Graphe nommé : http://example.org/alice
@prefix foaf: <http://xmlns.com/foaf/0.1/> .

_:a foaf:name "Alice" .
_:a foaf:mbox <mailto:alice@work.example.org> .
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX dc: <http://purl.org/dc/elements/1.1/>

SELECT ?who ?g ?mbox
FROM <http://example.org/dft.ttl>
FROM NAMED <http://example.org/alice>
FROM NAMED <http://example.org/bob>
WHERE
{
   ?g dc:publisher ?who .
   GRAPH ?g { ?x foaf:mbox ?mbox }
}

L'ensemble de données RDF de cette interrogation contient un graphe par défaut et deux graphes nommés. Le mot-clé GRAPH est décrit ci-dessous.

Les actions nécessaires pour construire l'ensemble de données ne sont pas déterminées par la seule description de l'ensemble de données. Si une adresse IRI apparaît deux fois dans une description d'ensemble de données, soit par deux clauses FROM, soit par une clause FROM et une clause FROM NAMED, alors cela ne suppose pas que sont faites une seule tentative exactement ou deux tentatives exactement pour obtenir un graphe RDF associé à l'adresse IRI. Dès lors, on ne peut faire aucune supposition à propos de l'identité des nœuds anonymes dans les triplets obtenus à partir des deux apparitions (occurrences) dans la description de l'ensemble de données. En général, on ne peut faire aucune supposition concernant l'équivalence des graphes.

8.3 Interrogation de l'ensemble de données

Lors de l'interrogation d'une collection de graphes, le mot-clé GRAPH est utilisé pour comparer des motifs à des graphes nommés. GRAPH peut fournir une adresse IRI pour sélectionner un seul graphe ou utiliser une variable qui s'étendra sur l'adresse IRI de tous les graphes nommés dans l'ensemble de données RDF de l'interrogation.

L'utilisation de GRAPH change le graphe actif pour le filtrage des motifs de graphe élémentaires dans une partie de l'interrogation. En dehors de l'utilisation de GRAPH, le graphe par défaut est filtré par des motifs de graphe élémentaires.

Dans les exemples, nous utiliserons les deux graphes suivants :

# Graphe nommé : http://example.org/foaf/aliceFoaf
@prefix  foaf:     <http://xmlns.com/foaf/0.1/> .
@prefix  rdf:      <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix  rdfs:     <http://www.w3.org/2000/01/rdf-schema#> .

_:a  foaf:name     "Alice" .
_:a  foaf:mbox     <mailto:alice@work.example> .
_:a  foaf:knows    _:b .

_:b  foaf:name     "Bob" .
_:b  foaf:mbox     <mailto:bob@work.example> .
_:b  foaf:nick     "Bobby" .
_:b  rdfs:seeAlso  <http://example.org/foaf/bobFoaf> .

<http://example.org/foaf/bobFoaf>
     rdf:type      foaf:PersonalProfileDocument .
# Graphe nommé : http://example.org/foaf/bobFoaf
@prefix  foaf:     <http://xmlns.com/foaf/0.1/> .
@prefix  rdf:      <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix  rdfs:     <http://www.w3.org/2000/01/rdf-schema#> .

_:z  foaf:mbox     <mailto:bob@work.example> .
_:z  rdfs:seeAlso  <http://example.org/foaf/bobFoaf> .
_:z  foaf:nick     "Robert" .

<http://example.org/foaf/bobFoaf>
     rdf:type      foaf:PersonalProfileDocument .
Règle de grammaire :
[24]   GraphGraphPattern   ::=   'GRAPH' VarOrIRIref GroupGraphPattern

8.3.1 Accès aux nomx de graphe

L'interrogation suivante compare le motif de graphe à chacun des graphes nommés dans l'ensemble de données et forme des solutions où la variable src est liée aux adresses IRI du graphe comparé. Le motif de graphe est comparé au graphe actif, c'est-à-dire chacun des graphes nommés dans l'ensemble de données.

PREFIX foaf: <http://xmlns.com/foaf/0.1/>

SELECT ?src ?bobNick
FROM NAMED <http://example.org/foaf/aliceFoaf>
FROM NAMED <http://example.org/foaf/bobFoaf>
WHERE
  {
    GRAPH ?src
    { ?x foaf:mbox <mailto:bob@work.example> .
      ?x foaf:nick ?bobNick
    }
  }

Le résultat d'interrogation donne le nom des graphes où l'information est trouvée et la valeur du surnom (nick) de Bob :

src bobNick
<http://example.org/foaf/aliceFoaf> "Bobby"
<http://example.org/foaf/bobFoaf> "Robert"

8.3.2 Restriction par adresse IRI de graphe

L'interrogation peut restreindre le filtrage appliqué à un graphe spécifique en fournissant l'adresse IRI du graphe. Cela établit le graphe nommé par l'addresse IRI comme graphe actif. Cette interrogation cherche le surnom de Bob tel que donné dans le graphe http://example.org/foaf/bobFoaf.

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX data: <http://example.org/foaf/>

SELECT ?nick
FROM NAMED <http://example.org/foaf/aliceFoaf>
FROM NAMED <http://example.org/foaf/bobFoaf>
WHERE
  {
     GRAPH data:bobFoaf {
         ?x foaf:mbox <mailto:bob@work.example> .
         ?x foaf:nick ?nick }
  }

ce qui produit une seule solution :

nick
"Robert"

8.3.3 Restriction des adresses IRI des graphes possibles

Une variable utilisée dans la clause GRAPH peut aussi l'être dans une autre clause GRAPH ou dans un motif de graphe comparé au graphe par défaut dans l'ensemble de données.

L'interrogation suivante utilise le graphe avec l'adresse IRI http://example.org/foaf/aliceFoaf pour trouver le document de profil de Bob ; puis elle compare un autre motif à ce graphe. Le motif dans la deuxième clause GRAPH trouve le nœud anonyme (variable w) de la personne avec la même boîte aux lettres (donnée par la variable mbox) que celle trouvée dans la première clause GRAPH (variable whom), parce que le nœud anonyme utilisé pour filtrer la variable whom du fichier FOAF d'Alice n'est pas le même que le nœud anonyme du document de profil (puisqu'ils se trouvent dans des graphes différents).

PREFIX  data:  <http://example.org/foaf/>
PREFIX  foaf:  <http://xmlns.com/foaf/0.1/>
PREFIX  rdfs:  <http://www.w3.org/2000/01/rdf-schema#>

SELECT ?mbox ?nick ?ppd
FROM NAMED <http://example.org/foaf/aliceFoaf>
FROM NAMED <http://example.org/foaf/bobFoaf>
WHERE
{
  GRAPH data:aliceFoaf
  {
    ?alice foaf:mbox <mailto:alice@work.example> ;
           foaf:knows ?whom .
    ?whom  foaf:mbox ?mbox ;
           rdfs:seeAlso ?ppd .
    ?ppd  a foaf:PersonalProfileDocument .
  } .
  GRAPH ?ppd
  {
      ?w foaf:mbox ?mbox ;
         foaf:nick ?nick
  }
}
mbox nick ppd
<mailto:bob@work.example> "Robert" <http://example.org/foaf/bobFoaf>

Un triplet dans le fichier FOAF d'Alice donnant le surnom (nick) de Bob ne sera pas utilisé pour fournir le surnom de Bob car le motif impliquant la variable nick est restreint par la variable ppd à un document de profil personnel (Personal Profile Document) particulier.

8.3.4 Graphes nommés et par défaut

Les motifs d'interrogation peuvent impliquer à la fois le graphe par défaut et les graphes nommés. Dans cet exemple, un agrégateur (aggregator) a lu une ressource web à deux occasions différentes. À chaque fois qu'un graphe est interprété dans l'agrégateur, il reçoit du système local une adresse IRI. Les graphes sont pratiquement les mêmes hormis l'adresse de courrier électronique de Bob qui a changé.

Ici le graphe par défaut est utilisé pour enregistrer les informations de provenance et les données RDF réellement lues sont conservées en deux graphes séparés, le système donnant à chacun une adresse IRI différente. L'ensemble de données RDF est constitué des deux graphes nommés et des informations à leur sujet.

RDF Dataset:

# Graphe par défaut
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix g:  <tag:example.org,2005-06-06:> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

g:graph1 dc:publisher "Bob" .
g:graph1 dc:date "2004-12-06"^^xsd:date .

g:graph2 dc:publisher "Bob" .
g:graph2 dc:date "2005-01-10"^^xsd:date .
# Graphe avec adresse IRI allouée localement : tag:example.org,2005-06-06:graph1
@prefix foaf: <http://xmlns.com/foaf/0.1/> .

_:a foaf:name "Alice" .
_:a foaf:mbox <mailto:alice@work.example> .

_:b foaf:name "Bob" .
_:b foaf:mbox <mailto:bob@oldcorp.example.org> .
# Graphe avec adresse IRI allouée localement : tag:example.org,2005-06-06:graph2
@prefix foaf: <http://xmlns.com/foaf/0.1/> .

_:a foaf:name "Alice" .
_:a foaf:mbox <mailto:alice@work.example> .

_:b foaf:name "Bob" .
_:b foaf:mbox <mailto:bob@newcorp.example.org> .

Cette interrogation découvre des adresses électroniques, en détaillant le nom de la personne et la date de découverte de l'information.

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX dc:   <http://purl.org/dc/elements/1.1/>

SELECT ?name ?mbox ?date
WHERE
  {  ?g dc:publisher ?name ;
        dc:date ?date .
    GRAPH ?g
      { ?person foaf:name ?name ; foaf:mbox ?mbox }
  }

Les résultats montrent que l'adresse électronique de "Bob" a changé.

name mbox date
"Bob" <mailto:bob@oldcorp.example.org> "2004-12-06"^^xsd:date
"Bob" <mailto:bob@newcorp.example.org> "2005-01-10"^^xsd:date

L'adresse IRI du type de donnée date est abrégée dans les résultats pour la lisibilité.

9 Séquences de solutions et modificateurs

Les motifs d'interrogation génèrent une collection non ordonnée de solutions, chaque solution étant une fonction partielle de variables vers des termes RDF. Ces solutions sont ensuite traitées comme une séquence (une séquence de solutions), d'abord sans ordre spécifique ; les éventuels modificateurs de séquence s'appliquent alors pour créer une autre séquence. Enfin, cette dernière séquence est utilisée pour générer un des résultats d'une forme d'interrogation SPARQL.

Un modificateur de séquence de solutions (solution sequence modifier) est l'un des suivants :

Les modificateurs s'appliquent dans l'ordre de la liste ci-dessus.

Règles de grammaire :
[5]   SelectQuery   ::=   'SELECT' ( 'DISTINCT' | 'REDUCED' )? ( Var+ | '*' ) DatasetClause* WhereClause SolutionModifier
[14]   SolutionModifier   ::=   OrderClause? LimitOffsetClauses?
[15]   LimitOffsetClauses   ::=   ( LimitClause OffsetClause? | OffsetClause LimitClause? )
[16]   OrderClause   ::=   'ORDER' 'BY' OrderCondition+

9.1 ORDER BY

La clause ORDER BY établit l'ordre d'une séquence de solutions.

À la suite de la clause ORDER BY on trouve une séquence de comparateurs de tri, composée d'une expression et d'un modificateur de tri optionnel — ASC() ou DESC(). Chaque comparateur de tri est soit ascendant — indiqué par le modificateur ASC() ou aucun modificateur —, soit descendant — indiqué par le modificateur DESC().

PREFIX foaf:    <http://xmlns.com/foaf/0.1/>

SELECT ?name
WHERE { ?x foaf:name ?name }
ORDER BY ?name
PREFIX     :    <http://example.org/ns#>
PREFIX foaf:    <http://xmlns.com/foaf/0.1/>
PREFIX xsd:     <http://www.w3.org/2001/XMLSchema#>

SELECT ?name
WHERE { ?x foaf:name ?name ; :empId ?emp }
ORDER BY DESC(?emp)
PREFIX foaf:    <http://xmlns.com/foaf/0.1/>

SELECT ?name
WHERE { ?x foaf:name ?name ; :empId ?emp }
ORDER BY ?name DESC(?emp)

L'opérateur "<" (cf. les sections 11.3 Conversion des opérateurs et 11.3.1 Extensibilité des opérateurs) définit l'ordre relatif de deux types numériques, littéraux simples, xsd:string, xsd:boolean et xsd:dateTime. On ordonne deux adresses IRI en les comparant comme des littéraux simples.

SPARQL établit également un classement entre certains types de termes RDF qui ne seraient pas ordonnés sinon :

  1. (Priorité la plus faible) aucune valeur n'est affectée à la variable ou à l'expression dans cette solution ;
  2. Les nœuds anonymes ;
  3. Les adresses IRI ;
  4. Les littéraux RDF.

Un littéral ordinaire (plain literal) est inférieur à un littéral RDF avec un type xsd:string de la même forme lexicale.

SPARQL ne définit pas le classement d'ensemble de tous les termes RDF possibles. Voici quelques exemples de couples de termes pour lesquels l'ordre relatif n'est pas défini :

Cette liste de liaisons de variables est en ordre ascendant :

Terme RDFRaison
Les résultats non liés sont triés comme étant en premier.
_:zLes nœuds anonymes suivent les non liés.
_:aIl n'y a pas de classement relatif des nœuds anonymes.
<http://script.example/Latin>Les adresses IRI suivent les nœuds anonymes.
<http://script.example/Кириллица>Le caractère cyrillique "К" en vingt-troisième position a un point de code Unicode 0x41A, lequel est supérieur à 0x4C ("L").
<http://script.example/漢字> Le caractère chinois "漢" en vingt-troisième position a un point de code Unicode 0x6F22, lequel est supérieur à 0x41A ("К").
"http://script.example/Latin"Les littéraux simples suivent les adresses IRI.
"http://script.example/Latin"^^xsd:stringLes types xsd:string suivent les littéraux simples.

L'ordre ascendant de deux solutions en fonction d'un comparateur de tri est établi en substituant les liaisons de solution dans les expressions et en les comparant avec l'opérateur "<". L'ordre descendant est l'inverse de l'ordre ascendant.

L'ordre relatif de deux solutions est celui des deux solutions en fonction du premier comparateur de tri dans la séquence. Pour les solutions où les substitutions des liaisons de solution produisent le même terme RDF, l'ordre relatif est celui des deux solutions en fonction du comparateur de tri suivant. L'ordre relatif de deux solutions n'est pas défini si aucune expression de tri évaluée dans les deux solutions ne produit de termes RDF distincts.

Le tri d'une séquence de solutions produit toujours une séquence contenant le même nombre de solutions.

L'utilisation du modificateur ORDER BY sur la séquence de solutions d'une interrogation de type CONSTRUCT ou DESCRIBE n'a aucun effet direct puisque seule une interrogation de type SELECT retourne une séquence de résultats. Lorsqu'utilisé en combinaison avec les modificateurs LIMIT et OFFSET, le modificateur ORDER BY peut servir à retourner des résultats générés à partir d'une tranche différente de la séquence de solutions. Une interrogation ASK ne contient pas de modificateurs ORDER BY, LIMIT ou OFFSET.

Règles de grammaire :
[16]   OrderClause   ::=   'ORDER' 'BY' OrderCondition+
[17]   OrderCondition   ::=   ( ( 'ASC' | 'DESC' ) BrackettedExpression )
| ( Constraint | Var )
[18]   LimitClause   ::=   'LIMIT' INTEGER
[19]   OffsetClause   ::=   'OFFSET' INTEGER

9.2 Projection

La séquence de solutions peut être transformée en une séquence n'impliquant qu'un sous-ensemble des variables. Pour chaque solution dans la séquence, une nouvelle solution est formée avec une sélection définie des variables en utilisant la forme d'interrogation SELECT.

Les exemples suivants montrent une interrogation pour n'extraire que les noms des personnes décrites dans un graphe RDF utilisant des propriétés FOAF :

@prefix foaf:        <http://xmlns.com/foaf/0.1/> .

_:a  foaf:name       "Alice" .
_:a  foaf:mbox       <mailto:alice@work.example> .

_:b  foaf:name       "Bob" .
_:b  foaf:mbox       <mailto:bob@work.example> .
PREFIX foaf:       <http://xmlns.com/foaf/0.1/>
SELECT ?name
WHERE
 { ?x foaf:name ?name }
name
"Bob"
"Alice"

9.3 Solutions en double

Une séquence de solutions sans les modificateurs DISTINCT ou REDUCED gardera les solutions en double.

@prefix  foaf:  <http://xmlns.com/foaf/0.1/> .

_:x    foaf:name   "Alice" .
_:x    foaf:mbox   <mailto:alice@example.com> .

_:y    foaf:name   "Alice" .
_:y    foaf:mbox   <mailto:asmith@example.com> .

_:z    foaf:name   "Alice" .
_:z    foaf:mbox   <mailto:alice.smith@example.com> .
PREFIX foaf:    <http://xmlns.com/foaf/0.1/>
SELECT ?name WHERE { ?x foaf:name ?name }
name
"Alice"
"Alice"
"Alice"

Les modificateurs DISTINCT et REDUCED contrôlent si les doubles sont inclus dans les résultats d'interrogation.

9.3.1 DISTINCT

Le modificateur de solution DISTINCT élimine les solutions en double. Spécifiquement, chaque solution liant les mêmes variables aux mêmes termes RDF est éliminée de la séquence de solutions.

PREFIX foaf:    <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?name WHERE { ?x foaf:name ?name }
name
"Alice"

Notez que les doubles, selon l'ordre des modificateurs de séquences de solutions, sont éliminés avant que les modificateurs LIMIT ou bien OFFSET ne s'appliquent.

9.3.2 REDUCED

Tandis que le modificateur DISTINCT assure l'élimination des solutions en double dans l'ensemble de solutions, le modificateur REDUCED permet simplement de les éliminer. La cardinalité d'un ensemble de liaisons de variables dans un ensemble de solutions REDUCED est d'au moins un et n'est pas supérieure à celle de l'ensemble de solutions sans les modificateurs DISTINCT ou REDUCED. Par exemple, en utilisant les données précédentes, l'interrogation ci-dessous :

PREFIX foaf:    <http://xmlns.com/foaf/0.1/>
SELECT REDUCED ?name WHERE { ?x foaf:name ?name }

peut avoir une, deux (c'est le cas ici) ou trois solutions :

name
"Alice"
"Alice"

9.4 OFFSET

Le modificateur OFFSET fait commencer les solutions générées après le nombre de solutions indiqué. Une valeur OFFSET de zéro n'a aucun effet.

L'emploi des modificateurs LIMIT et OFFSET pour sélectionner des sous-ensembles différents parmi les solutions d'interrogation n'aura pas d'utilité à moins d'en rendre l'ordre prévisible en utilisant le modificateur ORDER BY.

PREFIX foaf:    <http://xmlns.com/foaf/0.1/>

SELECT  ?name
WHERE   { ?x foaf:name ?name }
ORDER BY ?name
LIMIT   5
OFFSET  10

9.5 LIMIT

La clause LIMIT place une limite supérieure au nombre des solutions retournées. Si le nombre de solutions réel est supérieur à la limite, alors le nombre limite de solutions, au plus, sera retourné.

PREFIX foaf:    <http://xmlns.com/foaf/0.1/>

SELECT ?name
WHERE { ?x foaf:name ?name }
LIMIT 20

Aucun résultat n'est retourné pour une valeur LIMIT de 0. Une limite ne peut pas être négative.

10 Formes d'interrogation

SPARQL offre quatre formes d'interrogation (query forms). Ces formes d'interrogation utilisent les solutions du filtrage par motif (pattern matching) pour former des ensembles de résultats ou des graphes RDF. Les formes d'interrogation sont les suivantes :

SELECT
Retourne toutes les variables liées, ou un sous-ensemble de celles-ci, dans une comparaison de motifs d'interrogation (query pattern match).
CONSTRUCT
Retourne un graphe RDF construit en substituant des variables dans un ensemble de gabarits de triplet (triple templates).
ASK
Retourne un booléen indiquant si un motif d'interrogation correspond ou non.
DESCRIBE
Retourne un graphe RDF décrivant les ressources trouvées.

On peut utiliser le format XML des résultats de liaisons de variables SPARQL pour sérialiser l'ensemble de résultats d'une interrogation SELECT ou le résultat booléen d'une interrogation ASK.

10.1 SELECT

La forme SELECT des résultats retourne les variables et leurs liaisons directement. La syntaxe SELECT * est une abréviation pour sélectionner toutes les variables dans une interrogation.

@prefix  foaf:  <http://xmlns.com/foaf/0.1/> .

_:a    foaf:name   "Alice" .
_:a    foaf:knows  _:b .
_:a    foaf:knows  _:c .

_:b    foaf:name   "Bob" .

_:c    foaf:name   "Clare" .
_:c    foaf:nick   "CT" .

PREFIX foaf:    <http://xmlns.com/foaf/0.1/>
SELECT ?nameX ?nameY ?nickY
WHERE
  { ?x foaf:knows ?y ;
       foaf:name ?nameX .
    ?y foaf:name ?nameY .
    OPTIONAL { ?y foaf:nick ?nickY }
  }
nameX nameY nickY
"Alice" "Bob"
"Alice" "Clare" "CT"

Les ensembles de résultats peuvent être accédés par une interface de programmation (API) locale mais aussi être sérialisés en XML ou bien en un graphe RDF. Un format XML est décrit dans la spécification Format XML des résultats d'interrogation SPARQL, qui donne pour cet exemple :

<?xml version="1.0"?>
<sparql xmlns="http://www.w3.org/2005/sparql-results#">
  <head>
    <variable name="nameX"/>
    <variable name="nameY"/>
    <variable name="nickY"/>
  </head>
  <results>
    <result>
      <binding name="nameX">
        <literal>Alice</literal>
      </binding>
      <binding name="nameY">
        <literal>Bob</literal>
      </binding>
   </result>
    <result>
      <binding name="nameX">
        <literal>Alice</literal>
      </binding>
      <binding name="nameY">
        <literal>Clare</literal>
      </binding>
      <binding name="nickY">
        <literal>CT</literal>
      </binding>
    </result>
  </results>
</sparql>
Règle de grammaire :
[5]   SelectQuery   ::=   'SELECT' ( 'DISTINCT' | 'REDUCED' )? ( Var+ | '*' )
DatasetClause* WhereClause SolutionModifier

10.2 CONSTRUCT

La forme d'interrogation CONSTRUCT retourne un seul graphe RDF défini par un gabarit de graphe (graph template). Le résultat est un graphe RDF formé en prenant chaque solution d'interrogation dans la séquence de solutions, en substituant les variables dans le gabarit de graphe et en combinant les triplets en un seul graphe RDF par une union d'ensemble.

Si une telle instanciation produit un triplet contenant une variable non liée ou une structure RDF invalide, telle qu'un littéral en position de sujet ou de prédicat, alors ce triplet n'est pas inclus dans le graphe RDF de sortie. Le gabarit de graphe peut contenir des triplets sans variable — connu comme triplets de base (ground triples) ou triplets explicites — qui apparaissent également dans le graphe RDF de sortie retourné par la forme d'interrogation CONSTRUCT.

@prefix  foaf:  <http://xmlns.com/foaf/0.1/> .

_:a    foaf:name   "Alice" .
_:a    foaf:mbox   <mailto:alice@example.org> .
PREFIX foaf:    <http://xmlns.com/foaf/0.1/>
PREFIX vcard:   <http://www.w3.org/2001/vcard-rdf/3.0#>
CONSTRUCT   { <http://example.org/person#Alice> vcard:FN ?name }
WHERE       { ?x foaf:name ?name }

Cette interrogation crée des propriétés vcard à partir des informations FOAF :

@prefix vcard: <http://www.w3.org/2001/vcard-rdf/3.0#> .

<http://example.org/person#Alice> vcard:FN "Alice" .

10.2.1 Gabarits avec nœuds anonymes

Un gabarit peut créer un graphe RDF contenant des nœuds anonymes (blank nodes). Les étiquettes de nœud anonyme sont confinées (scoped) au gabarit de chaque solution. Si la même étiquette apparaît deux fois dans un gabarit, il sera alors créé un nœud anonyme pour chaque solution d'interrogation mais il y aura des nœuds anonymes différents pour les triplets générés par les autres solutions d'interrogation.

@prefix  foaf:  <http://xmlns.com/foaf/0.1/> .

_:a    foaf:givenname   "Alice" .
_:a    foaf:family_name "Hacker" .

_:b    foaf:firstname   "Bob" .
_:b    foaf:surname     "Hacker" .
PREFIX foaf:    <http://xmlns.com/foaf/0.1/>
PREFIX vcard:   <http://www.w3.org/2001/vcard-rdf/3.0#>

CONSTRUCT { ?x  vcard:N _:v .
            _:v vcard:givenName ?gname .
            _:v vcard:familyName ?fname }
WHERE
 {
    { ?x foaf:firstname ?gname } UNION  { ?x foaf:givenname   ?gname } .
    { ?x foaf:surname   ?fname } UNION  { ?x foaf:family_name ?fname } .
 }

Cette interrogation crée des propriétés vcard correspondant aux informations FOAF :

@prefix vcard: <http://www.w3.org/2001/vcard-rdf/3.0#> .

_:v1 vcard:N         _:x .
_:x vcard:givenName  "Alice" .
_:x vcard:familyName "Hacker" .

_:v2 vcard:N         _:z .
_:z vcard:givenName  "Bob" .
_:z vcard:familyName "Hacker" .

L'utilisation de la variable x dans le gabarit, laquelle sera liée ici aux nœuds anonymes avec les étiquettes _:a et _:b dans les données, crée des étiquettes de nœud anonyme différentes (_:v1 et _:v2) dans le graphe RDF résultant.

10.2.2 Accès aux graphes dans l'ensemble de données RDF

Avec CONSTRUCT, il est possible d'extraire des parties ou la totalité des graphes de l'ensemble de données RDF cible. Le premier exemple retourne le graphe (s'il existe dans l'ensemble de données) avec l'étiquette IRI http://example.org/aGraph ; sinon il retourne un graphe vide.

CONSTRUCT { ?s ?p ?o } WHERE { GRAPH <http://example.org/aGraph> { ?s ?p ?o } . }

L'accès au graphe peut être conditionné à d'autres informations. Par exemple, si le graphe par défaut contient des métadonnées à propos des graphes nommés dans l'ensemble de données, alors une interrogation telle que la suivante peut extraire un graphe fondé sur l'information concernant le graphe nommé :

PREFIX  dc: <http://purl.org/dc/elements/1.1/>
PREFIX app: <http://example.org/ns#>
CONSTRUCT { ?s ?p ?o } WHERE
 {
   GRAPH ?g { ?s ?p ?o } .
   { ?g dc:publisher <http://www.w3.org/> } .
   { ?g dc:date ?date } .
   FILTER ( app:customDate(?date) > "2005-02-28T00:00:00Z"^^xsd:dateTime ) .
 }

app:customDate identifiait une fonction d'extension pour transformer le format de données en un terme RDF xsd:dateTime.

Règle de grammaire :
[6]   ConstructQuery   ::=   'CONSTRUCT' ConstructTemplate
DatasetClause* WhereClause SolutionModifier

10.2.3 Modificateurs de solution et CONSTRUCT

Les modificateurs de solution d'une interrogation affectent les résultats d'une interrogation CONSTRUCT. Dans cet exemple, le graphe de sortie du gabarit CONSTRUCT est formé à partir de juste deux des solutions du filtrage par motif de graphe (graph pattern matching). L'interrogation produit un graphe avec les noms des personnes des deux premiers sites, trié par visites. Les triplets dans le graphe RDF ne sont pas ordonnés.

@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix site: <http://example.org/stats#> .

_:a foaf:name "Alice" .
_:a site:hits 2349 .

_:b foaf:name "Bob" .
_:b site:hits 105 .

_:c foaf:name "Eve" .
_:c site:hits 181 .
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX site: <http://example.org/stats#>

CONSTRUCT { [] foaf:name ?name }
WHERE
{ [] foaf:name ?name ;
     site:hits ?hits .
}
ORDER BY desc(?hits)
LIMIT 2
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
_:x foaf:name "Alice" .
_:y foaf:name "Eve" .

10.3 ASK

Les applications peuvent utiliser la forme ASK pour tester si un motif d'interrogation a une solution ou non. Aucune information n'est retournée concernant les solutions d'interrogation possibles, juste qu'il existe ou non une solution.

@prefix foaf:       <http://xmlns.com/foaf/0.1/> .

_:a  foaf:name       "Alice" .
_:a  foaf:homepage   <http://work.example.org/alice/> .

_:b  foaf:name       "Bob" .
_:b  foaf:mbox       <mailto:bob@work.example> .
PREFIX foaf:    <http://xmlns.com/foaf/0.1/>
ASK  { ?x foaf:name  "Alice" }
yes

La forme de cet ensemble de résultats dans le format XML des résultats d'interrogation SPARQL donne :

<?xml version="1.0"?>
<sparql xmlns="http://www.w3.org/2005/sparql-results#">
  <head></head>
  <results>
    <boolean>true</boolean>
  </results>
</sparql>

Avec les mêmes données, l'interrogation suivante ne retourne aucune correspondance car la variable mbox d'Alice n'est pas mentionnée.

PREFIX foaf:    <http://xmlns.com/foaf/0.1/>
ASK  { ?x foaf:name  "Alice" ;
          foaf:mbox  <mailto:alice@work.example> }
no
Règle de grammaire :
[8]   AskQuery   ::=   'ASK' DatasetClause* WhereClause

10.4 DESCRIBE (informatif)

La forme DESCRIBE retourne un seul graphe RDF de résultat contenant des données RDF à propos de ressources. Ces données ne sont pas prescrites par une interrogation SPARQL, où le client interrogeant aurait à connaître la structure du RDF dans la source des données, mais elles sont plutôt déterminées par le processeur d'interrogation SPARQL. Le motif d'interrogation est utilisé pour créer un ensemble de résultat. La forme DESCRIBE prend chaque ressource identifiée dans une solution, ainsi que toutes les ressources nommées directement par des adresses IRI, et assemble un seul graphe RDF en prenant une « description » qui peut provenir de toute information disponible y compris de l'ensemble de données RDF cible. La description est déterminée par le service d'interrogation. La syntaxe DESCRIBE * est une abréviation pour décrire toutes les variables dans une interrogation.

10.4.1 Adresses IRI explicites

La clause DESCRIBE elle-même peut prendre des adresses IRI pour identifier les ressources. L'interrogation DESCRIBE la plus simple consiste juste en une adresse IRI dans la clause DESCRIBE :

DESCRIBE <http://example.org/>

10.4.2 Identification des ressources

Les ressources à décrire peuvent également être prises dans les liaisons juqu'à une variable d'interrogation dans un ensemble de résultats. Cela permet une description des ressources, qu'elles soient identifiées par des adresses IRI ou par un nœud anonyme dans l'ensemble de données :

PREFIX foaf:   <http://xmlns.com/foaf/0.1/>
DESCRIBE ?x
WHERE    { ?x foaf:mbox <mailto:alice@org> }

La propriété foaf:mbox est définie comme étant une propriété de fonction symétrique (inverse function property) dans le vocabulaire FOAF. Si elle était traitée comme telle, cette interrogation retournerait des informations à propos d'une seule personne au plus. Par contre, si le motif d'interrogation a plusieurs solutions, les données RDF de chacune sont constituées de l'union de toutes les descriptions de graphe RDF.

PREFIX foaf:   <http://xmlns.com/foaf/0.1/>
DESCRIBE ?x
WHERE    { ?x foaf:name "Alice" }

Plus d'une adresse IRI ou variable peuvent être données :

PREFIX foaf:   <http://xmlns.com/foaf/0.1/>
DESCRIBE ?x ?y <http://example.org/>
WHERE    {?x foaf:knows ?y}

10.4.3 Descriptions des ressources

Le RDF retourné est déterminé par l'éditeur de l'information. Il s'agit de l'information utile dont dispose le service à propos d'une ressource. Elle peut inclure des informations à propos d'autres ressources : ainsi les données RDF pour un livre peuvent aussi inclure des détails concernant l'auteur.

Une interrogation simple telle que :

PREFIX ent:  <http://org.example.com/employees#>
DESCRIBE ?x WHERE { ?x ent:employeeId "1234" }

pourrait retourner une description de l'employé et d'autres détails potentiellement utiles :

@prefix foaf:   <http://xmlns.com/foaf/0.1/> .
@prefix vcard:  <http://www.w3.org/2001/vcard-rdf/3.0> .
@prefix exOrg:  <http://org.example.com/employees#> .
@prefix rdf:    <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix owl:    <http://www.w3.org/2002/07/owl#>

_:a     exOrg:employeeId    "1234" ;
       
foaf:mbox_sha1sum   "ABCD1234" ;
        vcard:N
         [ vcard:Family       "Smith" ;
           vcard:Given        "John"  ] .

foaf:mbox_sha1sum  rdf:type  owl:InverseFunctionalProperty .

comprenant la fermeture de nœud anonyme (blank node closure) de vcard:N du vocabulaire vcard. D'autres mécanismes sont possibles pour décider quelles informations il faut retourner, comme des descriptions liées concises (concise bounded descriptions) [CBD].

Pour un vocabulaire tel que FOAF, où les ressources sont typiquement des nœuds anonymes, retourner suffisamment d'information pour identifier un nœud tel que le nœud foaf:mbox_sha1sum de type InverseFunctionalProperty ainsi que des informations telles que le nom et d'autres détails enregistrés serait approprié. Dans l'exemple, la correspondance de la clause WHERE a été retournée mais ce n'est pas obligatoire.

Règle de grammaire :
[7]   DescribeQuery   ::=   'DESCRIBE' ( VarOrIRIref+ | '*' )
DatasetClause* WhereClause? SolutionModifier

11 Test des valeurs

Les clauses FILTER SPARQL restreignent les solutions d'une correspondance de motif de graphe selon une expression donnée. Spécifiquement, les clauses FILTER éliminent toutes les solutions, lorsqu'elles sont substituées dans l'expression, qui aboutissent à une valeur booléenne effective de false ou bien produisent une erreur. Les valeurs booléennes effectives sont définies à la section 11.2.2 Valeurs booléennes effectives et les erreurs à la section 2.3.1 Types d'erreurs dans la spécification XQuery 1.0 — Un langage d'interrogation XML [XQUERY]. Ces erreurs n'ont pas d'effets hors de l'évaluation de FILTER.

Les littéraux RDF peuvent avoir une adresse IRI de type de données :

@prefix a:          <http://www.w3.org/2000/10/annotation-ns#> .
@prefix dc:         <http://purl.org/dc/elements/1.1/> .

_:a   a:annotates   <http://www.w3.org/TR/rdf-sparql-query/> .
_:a   dc:date       "2004-12-31T19:00:00-05:00" .

_:b   a:annotates   <http://www.w3.org/TR/rdf-sparql-query/> .
_:b   dc:date       "2004-12-31T19:01:00-05:00"^^<http://www.w3.org/2001/XMLSchema#dateTime> .

L'objet du premier triplet dc:date n'a pas d'information de type. Celui du deuxième a le type de données xsd:dateTime.

Les expressions SPARQL sont construites conformément à la grammaire et elles fournissent un accès aux fonctions (nommées par une adresse IRI) et aux fonctions d'opérateurs (invoquées par des mots-clés et des symboles dans la grammaire SPARQL). Les opérateurs SPARQL peuvent être utilisés pour comparer les valeurs de littéraux typés :

PREFIX a:      <http://www.w3.org/2000/10/annotation-ns#>
PREFIX dc:     <http://purl.org/dc/elements/1.1/>
PREFIX xsd:    <http://www.w3.org/2001/XMLSchema#>

SELECT ?annot
WHERE { ?annot  a:annotates  <http://www.w3.org/TR/rdf-sparql-query/> .
        ?annot  dc:date      ?date .
        FILTER ( ?date > "2005-01-01T00:00:00Z"^^xsd:dateTime ) }

Les opérateurs SPARQL sont listés à la section 11.3 et associés à leurs productions dans la grammaire.

En outre, SPARQL permet d'invoquer des fonctions arbitraires, y compris un sous-ensemble des fonctions de transtypage (casting functions) XPath, listées à la section 11.5. Ces fonctions sont invoquées par leur nom (une adresse IRI) dans une interrogation SPARQL. Par exemple :

... FILTER ( xsd:dateTime(?date) < xsd:dateTime("2005-01-01T00:00:00Z") ) ...

Dans cette section, nous utilisons les conventions d'écriture suivantes :

11.1 Types de données des opérandes

Les fonctions et opérateurs SPARQL agissent sur les termes RDF et les variables SPARQL. Un sous-ensemble de ces fonctions et opérateurs provient des Fonctions et opérateurs XQuery 1.0 et XPath 2.0 [FUNCOP], lesquels ont des arguments et des types de retour à valeur typée XML Schema. Les littéraux typés RDF passés comme arguments à ces fonctions et opérateurs sont convertis (mapped to) en valeurs typées XML Schema avec la valeur de chaîne de la forme lexicale et un type de données atomique correspondant à l'adresse IRI de type de données. À l'inverse, les valeurs typées retournées sont converties en littéraux typés RDF de la même façon.

SPARQL a des opérateurs supplémentaires qui agissent sur des sous-ensembles de termes RDF spécifiques. Dans une référence de type, les termes suivants dénotent un littéral typé avec l'adresse IRI de type de données XML Schema correspondante [XSDT] :

Les termes suivants identifient les types supplémentaires utilisés dans les tests de valeurs SPARQL :

Les types suivants sont dérivés des types numériques et constituent des arguments valides pour les functions et opérateurs prenant des arguments numériques :

Des extensions du langage SPARQL peuvent traiter des types supplémentaires comme étant dérivés des types de données XML Schema.

11.2 Évaluation des filtres

SPARQL offre un sous-ensemble des fonctions et opérateurs définis par XQuery à la section Conversion des opérateurs. La section 2.2.3, Traitement des expressions, de la spécification XQuery 1.0 décrit l'invocation des fonctions XPath. Les règles suivantes soulignent les différences entre les modèles d'exécution et de données de XQuery et SPARQL :

La table de vérité logical-and et logical-or pour vrai (T), faux (F) et en erreur (E) est la suivante :

ABA || BA && B
TTTT
TFTF
FTTF
FFFF
TETE
ETTE
FEEF
EFEF
EEEE

11.2.1 Invocation

SPARQL définit une syntaxe pour invoquer les fonctions et les opérateurs sur une liste d'arguments. Ceux-ci sont invoqués comme suit :

Si l'une de ces étapes échoue, l'invocation génère une erreur. Les effets des erreurs sont définis dans la section 11.2 Évaluation des filtres.

11.2.2 Valeur booléenne effective

La valeur booléenne effective (effective boolean value), ou valeur EBV, est utilisée pour calculer les arguments des fonctions logiques logical-and, logical-or et fn:not, ainsi que pour évaluer le résultat d'une expression FILTER.

Les règles de valeur booléenne effective XQuery reposent sur la définition de la fonction fn:boolean XPath. Les règles suivantes reflètent celles de fn:boolean appliquées aux types d'argument présents dans les interrogations SPARQL :

Une valeur EBV de true est représentée par un littéral typé avec un type de données de xsd:boolean et une valeur lexicale de "true" ; une valeur EBV de false est représentée par un littéral typé avec un type de données de xsd:boolean et une valeur lexicale de "false".

11.3 Conversion des opérateurs

La grammaire SPARQL identifie un ensemble d'opérateurs (par exemple, &&, *, isIRI) utilisés pour construire des contraintes. Le tableau suivant associe chacune de ces productions grammaticales aux opérandes appropriés et une fonction opératrice définie soit dans la spécification Fonctions et opérateurs XQuery 1.0 et XPath 2.0 [FUNCOP], soit dans les opérateurs SPARQL indiqués à la section 11.4. À la sélection de la définition d'opérateur pour un ensemble de paramètres donné, c'est la définition avec les paramètres les plus spécifiques qui s'applique. Ainsi, pour l'évaluation de xsd:integer = xsd:signedInt, la définition de l'opérateur = avec deux paramètres numériques s'applique, plutôt que celle avec deux termes RDF. Le tableau est organisé de manière à ce que le candidat supérieur le plus viable soit le plus spécifique. Les opérateurs invoqués sans les opérandes appropriés produisent une erreur de type.

SPARQL suit le schéma de XPath pour les promotions de type numérique et la substitution de sous-type pour les arguments des opérateurs numériques. Les règles de conversion des opérateurs XPath pour les opérandes numériques (xsd:integer, xsd:decimal, xsd:float, xsd:double et les types dérivés d'un type numérique) s'appliquent également aux opérateurs SPARQL (cf. la spécification Langage de chemin XML (XPath) 2.0 [XPATH20] pour les définitions des promotions de type numérique et de la substitution de sous-type). Certains opérateurs sont associés à des expressions de fonction imbriquée, ainsi fn:not(op:numeric-equal(A, B)). Notez que, selon les définitions XPath, fn:not et op:numeric-equal produisent une erreur si leur argument est une erreur.

L'interclassement (collation) de la fonction fn:compare est défini par XPath et identifié par http://www.w3.org/2005/xpath-functions/collation/codepoint. Cet interclassement permet une comparaison de chaînes fondée sur les valeurs de point de code (codepoint). L'équivalence de la chaîne de points de code peut être testée par l'équivalence des termes RDF.

Opérateurs unaires SPARQL
Opérateur Type(A)FonctionType du résultat
Opérateurs unaires XQuery
! A xsd:boolean (EBV)fn:not(A)xsd:boolean
+ A numériqueop:numeric-unary-plus(A)numérique
- A numériqueop:numeric-unary-minus(A)numérique
Tests SPARQL, définis à la section 11.4
BOUND(A) variablebound(A)xsd:boolean
isIRI(A)
isURI(A)
terme RDFisIRI(A)xsd:boolean
isBLANK(A) terme RDFisBlank(A)xsd:boolean
isLITERAL(A) terme RDFisLiteral(A)xsd:boolean
Accesseurs SPARQL, définis à la section 11.4
STR(A) littéralstr(A)littéral simple
STR(A) IRIstr(A)littéral simple
LANG(A) littérallang(A)littéral simple
DATATYPE(A) littéral typédatatype(A)IRI
DATATYPE(A) littéral simpledatatype(A)IRI
Opérateurs binaires SPARQL
Opérateur Type(A)Type(B)FonctionType du résultat
Connecteurs logiques, définis à la section 11.4
A || B xsd:boolean (EBV)xsd:boolean (EBV)logical-or(A, B)xsd:boolean
A && B xsd:boolean (EBV)xsd:boolean (EBV)logical-and(A, B)xsd:boolean
Tests XPath
A = B numériquenumériqueop:numeric-equal(A, B)xsd:boolean
A = B littéral simplelittéral simpleop:numeric-equal(fn:compare(A, B), 0)xsd:boolean
A = B xsd:stringxsd:stringop:numeric-equal(fn:compare(STR(A), STR(B)), 0)xsd:boolean
A = B xsd:booleanxsd:booleanop:boolean-equal(A, B)xsd:boolean
A = B xsd:dateTimexsd:dateTimeop:dateTime-equal(A, B)xsd:boolean
A != B numériquenumériquefn:not(op:numeric-equal(A, B))xsd:boolean
A != B littéral simplelittéral simplefn:not(op:numeric-equal(fn:compare(A, B), 0))xsd:boolean
A != B xsd:stringxsd:stringfn:not(op:numeric-equal(fn:compare(STR(A), STR(B)), 0))xsd:boolean
A != B xsd:booleanxsd:booleanfn:not(op:boolean-equal(A, B))xsd:boolean
A != B xsd:dateTimexsd:dateTimefn:not(op:dateTime-equal(A, B))xsd:boolean
A < B numériquenumériqueop:numeric-less-than(A, B)xsd:boolean
A < B littéral simplelittéral simpleop:numeric-equal(fn:compare(A, B), -1)xsd:boolean
A < B xsd:stringxsd:stringop:numeric-equal(fn:compare(STR(A), STR(B)), -1)xsd:boolean
A < B xsd:booleanxsd:booleanop:boolean-less-than(A, B)xsd:boolean
A < B xsd:dateTimexsd:dateTimeop:dateTime-less-than(A, B)xsd:boolean
A > B numériquenumériqueop:numeric-greater-than(A, B)xsd:boolean
A > B littéral simplelittéral simpleop:numeric-equal(fn:compare(A, B), 1)xsd:boolean
A > B xsd:stringxsd:stringop:numeric-equal(fn:compare(STR(A), STR(B)), 1)xsd:boolean
A > B xsd:booleanxsd:booleanop:boolean-greater-than(A, B)xsd:boolean
A > B xsd:dateTimexsd:dateTimeop:dateTime-greater-than(A, B)xsd:boolean
A <= B numériquenumériquelogical-or(op:numeric-less-than(A, B), op:numeric-equal(A, B))xsd:boolean
A <= B littéral simplelittéral simplefn:not(op:numeric-equal(fn:compare(A, B), 1))xsd:boolean
A <= B xsd:stringxsd:stringfn:not(op:numeric-equal(fn:compare(STR(A), STR(B)), 1))xsd:boolean
A <= B xsd:booleanxsd:booleanfn:not(op:boolean-greater-than(A, B))xsd:boolean
A <= B xsd:dateTimexsd:dateTimefn:not(op:dateTime-greater-than(A, B))xsd:boolean
A >= B numériquenumériquelogical-or(op:numeric-greater-than(A, B), op:numeric-equal(A, B))xsd:boolean
A >= B littéral simplelittéral simplefn:not(op:numeric-equal(fn:compare(A, B), -1))xsd:boolean
A >= B xsd:stringxsd:stringfn:not(op:numeric-equal(fn:compare(STR(A), STR(B)), -1))xsd:boolean
A >= B xsd:booleanxsd:booleanfn:not(op:boolean-less-than(A, B))xsd:boolean
A >= B xsd:dateTimexsd:dateTimefn:not(op:dateTime-less-than(A, B))xsd:boolean
Arithmétique XPath
A * B numériquenumériqueop:numeric-multiply(A, B)numérique
A / B numériquenumériqueop:numeric-divide(A, B)numérique; but xsd:decimal if both operands are xsd:integer
A + B numériquenumériqueop:numeric-add(A, B)numérique
A - B numériquenumériqueop:numeric-subtract(A, B)numérique
Tests SPARQL, définis à la section 11.4
A = B terme RDFterme RDFRDFterm-equal(A, B)xsd:boolean
A != B terme RDFterme RDFfn:not(RDFterm-equal(A, B))xsd:boolean
sameTERM(A) terme RDFterme RDFsameTerm(A, B)xsd:boolean
langMATCHES(A, B) littéral simplelittéral simplelangMatches(A, B)xsd:boolean
REGEX(STRING, PATTERN) littéral simplelittéral simplefn:matches(STRING, PATTERN)xsd:boolean
Opérateurs trinaires SPARQL
Opérateur Type(A)Type(B)Type(C)FonctionType du résultat
Tests SPARQL, définis à la section 11.4
REGEX(STRING, PATTERN, FLAGS) littéral simplelittéral simplelittéral simplefn:matches(STRING, PATTERN, FLAGS)xsd:boolean

Les arguments de fonction de type xsd:boolean signalés par "(EBV)" sont forcés à xsd:boolean en évaluant la valeur booléenne effective de l'argument.

11.3.1 Extensibilité des opérateurs

Les extensions du langage SPARQL peuvent fournir des conversions supplémentaires entre les opérateurs et les fonctions opératrices ; cela revient à ajouter des rangées aux tableaux ci-dessus. Aucun opérateur supplémentaire ne peut produire un résultat qui remplace un résultat, hormis une erreur de type, dans la sémantique définie précédemment. La conséquence de cette règle est que les extensions SPARQL produiront au moins les mêmes solutions qu'une mise en œuvre non étendue et qu'elles pourront produire, pour certaines interrogations, plus de solutions.

Les conversions supplémentaires de l'opérateur "<" sont censées contrôler l'ordre relatif des opérandes, spécifiquement lorsqu'il est utilisé dans une clause ORDER BY.

11.4 Définitions des opérateurs

Cette section définit les opérateurs introduits par le langage d'interrogation SPARQL. Les exemples montrent l'action des opérateurs tels qu'invoqués par les structures grammaticales appropriées.

11.4.1 bound

xsd:boolean   bound (variable var)

Retourne true si le paramètre var est lié à une valeur ; retourne false sinon. Les variables ayant les valeurs NaN ou INF sont considérées comme liées.

Données :

@prefix foaf:        <http://xmlns.com/foaf/0.1/> .
@prefix dc:          <http://purl.org/dc/elements/1.1/> .
@prefix xsd:          <http://www.w3.org/2001/XMLSchema#> .

_:a  foaf:givenName  "Alice".

_:b  foaf:givenName  "Bob" .
_:b  dc:date         "2005-04-04T04:04:04Z"^^xsd:dateTime .
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX dc:   <http://purl.org/dc/elements/1.1/>
PREFIX xsd:   <http://www.w3.org/2001/XMLSchema#>
SELECT ?name
 WHERE { ?x foaf:givenName  ?givenName .
         OPTIONAL { ?x dc:date ?date } .
         FILTER ( bound(?date) ) }

Résultat d'interrogation :

givenName
"Bob"

On peut tester qu'un motif de graphe n'est pas exprimé en définissant un motif de graphe OPTIONAL qui introduit une variable et en vérifiant que la variable n'est pas liée (not bound). C'est ce qu'on appelle « négation par l'échec » (negation as failure) en programmation logique.

Cette interrogation filtre les personnes avec un nom (name) mais sans date exprimée :

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX dc:   <http://purl.org/dc/elements/1.1/>
SELECT ?name
 WHERE { ?x foaf:givenName  ?name .
         OPTIONAL { ?x dc:date ?date } .
         FILTER (!bound(?date)) }

Résultat d'interrogation :

name
"Alice"

Puisque la date (dc:date) de Bob était connue, "Bob" ne constituait pas une solution de l'interrogation.

11.4.2 isIRI

xsd:boolean   isIRI (terme RDF term)
xsd:boolean   isURI (terme RDF term)

Retourne true si le paramètre term est de type IRI ; retourne false sinon. isURI est une orthographe alternative pour l'opérateur isIRI.

@prefix foaf:       <http://xmlns.com/foaf/0.1/> .

_:a  foaf:name       "Alice".
_:a  foaf:mbox       <mailto:alice@work.example> .

_:b  foaf:name       "Bob" .
_:b  foaf:mbox       "bob@work.example" .

Cette interrogation filtre les personnes avec un nom (name) et une boîte aux lettres (mbox) qui est une adresse IRI :

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name ?mbox
 WHERE { ?x foaf:name  ?name ;
            foaf:mbox  ?mbox .
         FILTER isIRI(?mbox) }

Résultat d'interrogation :

name mbox
"Alice" <mailto:alice@work.example>

11.4.3 isBlank

xsd:boolean   isBlank (terme RDF term)

Retourne true si le paramètre term est un nœud anonyme ; retourne false sinon.

@prefix a:          <http://www.w3.org/2000/10/annotation-ns#> .
@prefix dc:         <http://purl.org/dc/elements/1.1/> .
@prefix foaf:       <http://xmlns.com/foaf/0.1/> .

_:a   a:annotates   <http://www.w3.org/TR/rdf-sparql-query/> .
_:a   dc:creator    "Alice B. Toeclips" .

_:b   a:annotates   <http://www.w3.org/TR/rdf-sparql-query/> .
_:b   dc:creator    _:c .
_:c   foaf:given    "Bob".
_:c   foaf:family   "Smith".

Cette interrogation filtre les personnes avec une date (dc:creator) qui utilisent des prédicats du vocabulaire FOAF pour exprimer leur nom.

PREFIX a:      <http://www.w3.org/2000/10/annotation-ns#>
PREFIX dc:     <http://purl.org/dc/elements/1.1/>
PREFIX foaf:   <http://xmlns.com/foaf/0.1/>

SELECT ?given ?family
 WHERE { ?annot  a:annotates  <http://www.w3.org/TR/rdf-sparql-query/> .
         ?annot  dc:creator   ?c .
         OPTIONAL { ?c  foaf:given   ?given ; foaf:family  ?family } .
         FILTER isBlank(?c)
       }

Résultat d'interrogation :

given family
"Bob" "Smith"

Dans cet exemple, il y avait deux objets de prédicats foaf:knows mais un seul (_:c) était un nœud anonyme.

11.4.4 isLiteral

xsd:boolean   isLiteral (terme RDF term)

Retourne true si le paramètre term est un littéral ; retourne false sinon.

@prefix foaf:       <http://xmlns.com/foaf/0.1/> .

_:a  foaf:name       "Alice".
_:a  foaf:mbox       <mailto:alice@work.example> .

_:b  foaf:name       "Bob" .
_:b  foaf:mbox       "bob@work.example" .

Cette interrogation est similaire à celle de la section 11.4.2 sauf qu'elle filtre les personnes avec un nom (name) et une boîte aux lettres (mbox) qui est un littéral. Elle pourrait servir à repérer des données erronées (foaf:mbox devrait seulement avoir une adresse IRI comme objet).

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name ?mbox
 WHERE { ?x foaf:name  ?name ;
           foaf:mbox  ?mbox .
         FILTER isLiteral(?mbox) }

Résultat d'interrogation :

name mbox
"Bob" "bob@work.example"

11.4.5 str

littéral simple   str (littéral ltrl)
littéral simple   str (IRI rsrc)

Retourne la forme lexicale du paramètre ltrl (un littéral) ; retourne la représentation en points de code du paramètre rsrc (une adresse IRI). C'est utile pour examiner les parties d'une adresse IRI, par exemple le nom d'hôte.

@prefix foaf:       <http://xmlns.com/foaf/0.1/> .

_:a  foaf:name       "Alice".
_:a  foaf:mbox       <mailto:alice@work.example> .

_:b  foaf:name       "Bob" .
_:b  foaf:mbox       <mailto:bob@home.example> .

Cette interrogation sélectionne l'ensemble des personnes utilisant une adresse en work.example dans leur profil FOAF :

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name ?mbox
 WHERE { ?x foaf:name  ?name ;
            foaf:mbox  ?mbox .
         FILTER regex(str(?mbox), "@work.example") }

Résultat d'interrogation :

name mbox
"Alice" <mailto:alice@work.example>

11.4.6 lang

littéral simple   lang (littéral ltrl)

Retourne l'étiquette de langue du paramètre ltrl, le cas échéant ; retourne "" si ltrl n'a pas d'étiquette de langue. Notez que le modèle de données RDF n'inclut pas de littéraux avec étiquette de langue vide.

@prefix foaf:       <http://xmlns.com/foaf/0.1/> .

_:a  foaf:name       "Robert"@EN.
_:a  foaf:name       "Roberto"@ES.
_:a  foaf:mbox       <mailto:bob@work.example> .

Cette interrogation trouve le nom (foaf:name) espagnol et la boîte aux lettres (foaf:mbox) :

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name ?mbox
 WHERE { ?x foaf:name  ?name ;
            foaf:mbox  ?mbox .
         FILTER ( lang(?name) = "ES" ) }

Résultat d'interrogation :

name mbox
"Roberto"@ES <mailto:bob@work.example>

11.4.7 datatype

IRI   datatype (littéral typé typedLit)
IRI   datatype (littéral simple simpleLit)

Retourne l'adresse IRI de type de données du paramètre typedLit ; retourne un type xsd:string si le paramètre est un littéral simple.

@prefix foaf:       <http://xmlns.com/foaf/0.1/> .
@prefix eg:         <http://biometrics.example/ns#> .
@prefix xsd:        <http://www.w3.org/2001/XMLSchema#> .

_:a  foaf:name       "Alice".
_:a  eg:shoeSize     "9.5"^^xsd:float .

_:b  foaf:name       "Bob".
_:b  eg:shoeSize     "42"^^xsd:integer .

Cette interrogation trouve le nom (foaf:name) et la taille de chaussure (foaf:shoeSize) des personnes, la taille étant un entier :

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX xsd:  <http://www.w3.org/2001/XMLSchema#>
PREFIX eg:   <http://biometrics.example/ns#>
SELECT ?name ?shoeSize
 WHERE { ?x foaf:name  ?name ; eg:shoeSize  ?shoeSize .
         FILTER ( datatype(?shoeSize) = xsd:integer ) }

Résultat d'interrogation :

name shoeSize
"Bob" 42

11.4.8 logical-or

xsd:boolean   xsd:boolean left || xsd:boolean right

Retourne un OU logique des paramètres left et right. Notez que la fonction logical-or agit sur la valeur booléenne effective de ses arguments.

Remarque : cf. la section 11.2 Évaluation des filtres pour le traitement des erreurs de l'opérateur ||.

11.4.9 logical-and

xsd:boolean   xsd:boolean left && xsd:boolean right

Retourne un ET logique des paramètres left et right. Notez que la fonction logical-and agit sur la valeur booléenne effective de ses arguments.

Remarque : cf. la section 11.2 Évaluation des filtres pour le traitement des erreurs de l'opérateur &&.

11.4.10 RDFterm-equal

xsd:boolean   terme RDF term1 = terme RDF term2

Retourne true si les paramètres term1 et term2 sont le même terme RDF selon la définition de la spécification Cadre de description des ressources (RDF) — Concepts et syntaxe abstraite [CONCEPTS] ; produit une erreur de type si les deux arguments sont des littéraux mais pas le même terme RDF 1 ; retourne false sinon. Les paramètres term1 et term2 sont les mêmes si l'une des propositions suivantes est vraie :

@prefix foaf:       <http://xmlns.com/foaf/0.1/> .

_:a  foaf:name       "Alice".
_:a  foaf:mbox       <mailto:alice@work.example> .

_:b  foaf:name       "Ms A.".
_:b  foaf:mbox       <mailto:alice@work.example> .

Cette interrogation trouve les personnes qui ont plusieurs triplets foaf:name :

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name1 ?name2
 WHERE { ?x foaf:name  ?name1 ;
            foaf:mbox  ?mbox1 .
         ?y foaf:name  ?name2 ;
            foaf:mbox  ?mbox2 .
         FILTER (?mbox1 = ?mbox2 && ?name1 != ?name2)
       }

Résultat d'interrogation :

name1 name2
"Alice" "Ms A."
"Ms A." "Alice"

Dans l'interrogation suivante pour des documents annotés le jour de l'an (2004 ou 2005), les termes RDF ne sont pas les mêmes mais ont des valeurs équivalentes :

@prefix a:          <http://www.w3.org/2000/10/annotation-ns#> .
@prefix dc:         <http://purl.org/dc/elements/1.1/> .

_:b   a:annotates   <http://www.w3.org/TR/rdf-sparql-query/> .
_:b   dc:date       "2004-12-31T19:00:00-05:00"^^<http://www.w3.org/2001/XMLSchema#dateTime> .
PREFIX a:      <http://www.w3.org/2000/10/annotation-ns#>
PREFIX dc:     <http://purl.org/dc/elements/1.1/>
PREFIX xsd:    <http://www.w3.org/2001/XMLSchema#>

SELECT ?annotates
WHERE { ?annot  a:annotates  ?annotates .
        ?annot  dc:date      ?date .
        FILTER ( ?date = xsd:dateTime("2005-01-01T00:00:00Z") ) }
annotates
<http://www.w3.org/TR/rdf-sparql-query/>

[1] L'invocation de la fonction RDFterm-equal sur deux littéraux typés teste l'équivalence des valeurs. Une mise en œuvre étendue peut gérer des types de données supplémentaires. Une mise en œuvre traitant une interrogation qui teste l'équivalence des valeurs sur des types de données non gérés (et des formes lexicales et des adresses IRI de type de données non identiques) retourne une erreur, indiquant par-là qu'elle est incapable de déterminer si les valeurs sont équivalentes ou non. Ainsi, une mise en œuvre non étendue produira une erreur en testant "iiii"^^my:romanNumeral = "iv"^^my:romanNumeral, ou bien "iiii"^^my:romanNumeral != "iv"^^my:romanNumeral.

11.4.11 sameTerm

xsd:boolean   sameTerm (terme RDF term1, terme RDF term2)

Retourne true si les paramètres term1 et term2 sont le même terme RDF comme défini dans la spécification Cadre de description des ressources (RDF) — Concepts et syntaxe abstraite [CONCEPTS] ; retourne false sinon.

@prefix foaf:       <http://xmlns.com/foaf/0.1/> .

_:a  foaf:name       "Alice".
_:a  foaf:mbox       <mailto:alice@work.example> .

_:b  foaf:name       "Ms A.".
_:b  foaf:mbox       <mailto:alice@work.example> .

Cette interrogation trouve les personnes qui ont plusieurs triplets foaf:name :

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name1 ?name2
 WHERE { ?x foaf:name  ?name1 ;
            foaf:mbox  ?mbox1 .
         ?y foaf:name  ?name2 ;
            foaf:mbox  ?mbox2 .
         FILTER (sameTerm(?mbox1, ?mbox2) && !sameTerm(?name1, ?name2))
       }

Résultat d'interrogation :

name1 name2
"Alice" "Ms A."
"Ms A." "Alice"

À la différence de RDFterm-equal, la fonction sameTerm peut être utilisée pour tester la non-équivalence de littéraux typés ayant des types de données non gérés :

@prefix :          <http://example.org/WMterms#> .
@prefix t:         <http://example.org/types#> .

_:c1  :label        "Container 1" .
_:c1  :weight       "100"^^t:kilos .
_:c1  :displacement  "100"^^t:liters .

_:c2  :label        "Container 2" .
_:c2  :weight       "100"^^t:kilos .
_:c2  :displacement  "85"^^t:liters .

_:c3  :label        "Container 3" .
_:c3  :weight       "85"^^t:kilos .
_:c3  :displacement  "85"^^t:liters .
PREFIX  :      <http://example.org/WMterms#>
PREFIX  t:     <http://example.org/types#>

SELECT ?aLabel1 ?bLabel
WHERE { ?a  :label        ?aLabel .
        ?a  :weight       ?aWeight .
        ?a  :displacement ?aDisp .

        ?b  :label        ?bLabel .
        ?b  :weight       ?bWeight .
        ?b  :displacement ?bDisp .

        FILTER ( sameTerm(?aWeight, ?bWeight) && !sameTerm(?aDisp, ?bDisp) }
aLabel bLabel
"Container 1" "Container 2"
"Container 2" "Container 1"

Le test des boîtes avec le même poids peut aussi être réalisé avec l'opérateur "=" (cf. RDFterm-equal) puisque le test "100"^^t:kilos = "85"^^t:kilos aboutira à une erreur, éliminant ainsi cette solution potentielle.

11.4.12 langMatches

xsd:boolean   langMatches (littéral simple language-tag, littéral simple language-range)

Retourne true si le premier argument language-tag correspond au deuxième argument language-range selon le schéma de filtrage de base défini dans [RFC4647], section 3.3.1. L'argument language-range est une étendue de langue de base selon le RFC Correspondance des étiquettes de langue [RFC4647], section 2.1. Un argument language-range de "*" filtre toute chaîne language-tag non vide.

@prefix dc:       <http://purl.org/dc/elements/1.1/> .

_:a  dc:title         "That Seventies Show"@en .
_:a  dc:title         "Cette série des années soixante-dix"@fr .
_:a  dc:title         "Cette série des années septante"@fr-BE .
_:b  dc:title         "Il Buono, il Bruto, il Cattivo" .

Cette interrogation utilise les fonctions langMatches et lang (décrites à la section 11.2.3.8) pour trouver les titres en français de la série anglaise intitulée « That Seventies Show » :

PREFIX dc: <http://purl.org/dc/elements/1.1/>
SELECT ?title
 WHERE { ?x dc:title  "That Seventies Show"@en ;
            dc:title  ?title .
         FILTER langMatches( lang(?title), "FR" ) }

Résultat d'interrogation :

title
"Cette série des années soixante-dix"@fr
"Cette série des années septante"@fr-BE

L'idiome langMatches( lang( ?v ), "*" ) ne filtrera pas les littéraux sans étiquette de langue puisque lang( ?v ) retournera une chaîne vide, donc :

PREFIX dc: <http://purl.org/dc/elements/1.1/>
SELECT ?title
 WHERE { ?x dc:title  ?title .
         FILTER langMatches( lang(?title), "*" ) }

signalera tous les titres avec une étiquette de langue :

title
"That Seventies Show"@en
"Cette série des années soixante-dix"@fr
"Cette série des années septante"@fr-BE

11.4.13 regex

xsd:boolean   regex (littéral simple text, littéral simple pattern)
xsd:boolean   regex (littéral simple text, littéral simple pattern, littéral simple flags)

Invoque la fonction XPath fn:matches pour filtrer l'argument text par rapport à un motif d'expression rationnelle (argument pattern). Le langage d'expression rationnelle est défini dans les Fonctions et opérateurs XQuery 1.0 et XPath 2.0, à la section 7.6.1 Syntaxe des expressions rationnelles [FUNCOP].

@prefix foaf:       <http://xmlns.com/foaf/0.1/> .

_:a  foaf:name       "Alice".
_:b  foaf:name       "Bob" .
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name
 WHERE { ?x foaf:name  ?name
         FILTER regex(?name, "^ali", "i") }

Résultat d'interrogation :

name
"Alice"

11.5 Fonctions constructrices

SPARQL importe un sous-ensemble des fonctions constructrices (constructor functions) XPath définies dans les Fonctions et opérateurs XQuery 1.0 et XPath 2.0 [FUNCOP], section 17.1 Forçage de types primitifs à types primitifs. Les constructeurs SPARQL comprennent tous les constructeurs XPath pour les types de données d'opérandes SPARQL plus les types de données supplémentaires imposés par le modèle de données RDF. Dans SPARQL, le transtypage (casting) s'effectue en appelant une fonction constructrice pour le type cible sur un opérande du type source.

XPath définit seulement le forçage d'un seul type de données XML Schema à un autre. Les forçages restants sont définis comme suit :

Le tableau ci-dessous récapitule les opérations de transtypage toujours permises (Y), jamais permises (N) et dépendantes de la valeur lexicale (M). Par exemple, une opération de transtypage d'un type xsd:string (première rangée) vers un type xsd:float (deuxième colonne) dépend de la valeur lexicale (M).

bool = xsd:boolean
dbl = xsd:double
flt = xsd:float
dec = xsd:decimal
int = xsd:integer
dT = xsd:dateTime
str = xsd:string
IRI = IRI
ltrl = littéral simple

De \ À str flt dbl dec int dT bool
str Y M M M M M M
flt Y Y Y M M N Y
dbl Y Y Y M M N Y
dec Y Y Y Y Y N Y
int Y Y Y Y Y N Y
dT Y N N N N Y N
bool Y Y Y Y Y N Y
IRI Y N N N N N N
ltrl Y M M M M M M

11.6 Test des valeurs extensibles

Une règle de grammaire PrimaryExpression peut consister en un appel à une fonction d'extension nommée par une adresse IRI. Une fonction d'extension reçoit un certain nombre de termes RDF en arguments et retourne un terme RDF. La sémantique de ces fonctions est définie par l'adresse IRI qui identifie la fonction.

L'interopérabilité des interrogations SPARQL utilisant des fonctions d'extension sera vraisemblablement limitée.

Comme exemple, prenons une fonction appelée func:even :

xsd:boolean   func:even (numérique value)

Cette fonction serait invoquée dans un filtre (FILTER) ainsi :

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX func: <http://example.org/functions#>
SELECT ?name ?id
WHERE { ?x foaf:name  ?name ;
           func:empId   ?id .
        FILTER (func:even(?id)) }

Comme deuxième exemple, prenons une fonction aGeo:distance qui calcule la distance entre deux points, utilisée ici pour trouver des lieux près de Grenoble :

xsd:double   aGeo:distance (numérique x1, numérique y1, numérique x2, numérique y2)
PREFIX aGeo: <http://example.org/geo#>

SELECT ?neighbor
WHERE { ?a aGeo:placeName "Grenoble" .
        ?a aGeo:location ?axLoc .
        ?a aGeo:location ?ayLoc .

        ?b aGeo:placeName ?neighbor .
        ?b aGeo:location ?bxLoc .
        ?b aGeo:location ?byLoc .

        FILTER ( aGeo:distance(?axLoc, ?ayLoc, ?bxLoc, ?byLoc) < 10 ) .
      }

On pourrait utiliser une fonction d'extension pour tester un type de données d'application non géré par la spécification SPARQL de base ; ce pourrait être une transformation entre des formats de types de données, par exemple, vers un terme RDF dateTime XSD depuis un autre format de date.

12 Définition de SPARQL

Cette section définit le comportement correct pour l'évaluation de motifs de graphe et de modificateurs de solution, en fonction d'une chaîne d'interrogation et d'un ensemble de données RDF. Cela n'implique pas qu'une mise en œuvre SPARQL doive utiliser le processus défini ici.

L'exécution d'une interrogation SPARQL est définie par une série d'étapes, commençant à l'interrogation SPARQL en tant que chaîne, en transformant cette chaîne en une forme de syntaxe abstraite, puis en transformant la syntaxe abstraite en une interrogation abstraite SPARQL comprenant des opérateurs de l'algèbre SPARQL. Cette interrogation abstraite est alors évaluée sur un ensemble de données RDF.

12.1 Définitions initiales

12.1.1 Termes RDF

SPARQL est défini en fonction d'adresses IRI [RFC3987]. Les adresses IRI constituent un sous-ensemble des références URI RDF qui omet les espaces.

Définition : terme RDF (RDF term)

Soit I l'ensemble de toutes les adresses IRI ;
soit RDF-L l'ensemble de tous les littéraux RDF ;
soit RDF-B l'ensemble de tous les nœuds anonymes dans les graphes RDF.

L'ensemble des termes RDF, RDF-T, est : I union RDF-L union RDF-B.

Cette définition d'un terme RDF rassemble plusieurs notions de base du modèle de données RDF, toutefois mises à jour pour indiquer des adresses IRI au lieu de références URI RDF.

12.1.2 Ensemble de données RDF

Définition : ensemble de données RDF (RDF dataset)

Un ensemble de données RDF est un ensemble tel que :
{ G, (<u1>, G1), (<u2>, G2), ..., (<un>, Gn) }
où G et chaque Gi sont des graphes, et chaque <ui> est une adresse IRI. Chaque <ui> est distinct.

G est dit le graphe par défaut. (<ui>, Gi) sont dits des graphes nommés.

Définition : graphe actif (active graph)

Le graphe actif est le graphe de l'ensemble de données utilisé pour le filtrage des motifs de graphe élémentaires.

12.1.3 Variables d'interrogation

Définition : variable d'interrogation (query variable)

Une variable d'interrogation est un membre de l'ensemble V, où V est infini et disjoint de l'ensemble RDF-T.

12.1.4 Motifs de triplet

Définition : motif de triplet (triple pattern)

Un motif de triplet est membre de l'ensemble :
(RDF-T union V) x (I union V) x (RDF-T union V)

Cette définition du motif de triplet inclut les sujets littéraux. Voici ce que fait remarquer le groupe de travail RDF-core.

« [Le groupe de travail RDF core] remarquait ne voir aucune objection à ce que les littéraux soient des sujets et un prochain groupe de travail avec une charte moins restrictive pourrait étendre les syntaxes pour admettre les littéraux comme sujets de déclarations. »

Du fait que les graphes RDF ne peuvent pas contenir de sujets littéraux, tout motif de triplet SPARQL avec un littéral pour sujet échouera à correspondre à un graphe RDF.

12.1.5 Motifs de graphe élémentaires

Définition : motif de graphe élémentaire (basic graph pattern)

Un motif de graphe élémentaire est un ensemble de motifs de triplet.

Le motif de graphe vide est un motif de graphe élémentaire qui est l'ensemble vide.

12.1.6 Application de solution

Une application de solution est une application d'un ensemble de variables vers un ensemble de termes RDF. Nous employons le terme « solution » là où cela est clair.

Définition : application de solution (solution mapping)

Une application de solution, μ, est une fonction partielle μ : V → T.

Le domaine de définition (domain) de μ, dom(μ), est le sous-ensemble de V où μ est définie.

Définition : séquence de solutions (solution sequence)

Une séquence de solutions est une liste de solutions éventuellement non ordonnées.

12.1.7 Modificateurs de séquence de solutions

Définition : modificateur de séquence de solutions (solution sequence modifier)

Un modificateur de séquence de solutions est l'un des modificateurs suivants :

12.2 Interrogation SPARQL

Cette section définit le processus de conversion des motifs de graphe et des modificateurs de solution dans une chaîne d'interrogation SPARQL en une expression algébrique SPARQL.

Après l'analyse d'une chaîne d'interrogation SPARQL et l'application des abréviations pour les adresses IRI et les motifs de triplet indiquée à la section 4, on obtient un arbre de syntaxe abstrait composé de :

Motifs Modificateurs Formes d'interrogation
termes RDF DISTINCT SELECT
motifs de triplet REDUCED CONSTRUCT
Motifs de graphe élémentaires PROJECT DESCRIBE
Groupes ORDER BY ASK
OPTIONAL LIMIT  
UNION OFFSET  
GRAPH    
FILTER    

Le résultat de la conversion de cet arbre de syntaxe abstrait est une interrogation SPARQL qui utilise les symboles algébriques SPARQL suivants :

Motif de graphe Modificateurs de solution
BGP ToList
Join OrderBy
LeftJoin Project
Filter Distinct
Union Reduced
Graph Slice

Slice est la combinaison des modificateurs OFFSET et LIMIT ; mod représente l'un des modificateurs de solution.

ToList est utilisé là où se produit la conversion des résultats du filtrage des motifs de graphe en séquences.

Définition : interrogation SPARQL (SPARQL query)

Une interrogation abstraite SPARQL est un uplet (tuple) (E, DS, R) où :

12.2.1 Conversions des motifs de graphe

Cette section décrit le processus de traduction d'un motif de graphe SPARQL en une expression algébrique SPARQL. Après la traduction des abréviations syntaxiques pour les adresses IRI et les motifs de triplet, il transforme récursivement les formes syntaxiques en expressions algébriques :

Le groupe de travail remarque que le point où s'applique l'étape de simplification conduit à une transformation ambiguë des interrogations impliquant un filtre et un motif doublement imbriqués :
OPTIONAL { { ... FILTER ( ... ?x ... ) } }.

Cela est illustré par deux cas d'utilisation non normatifs :

D'abord, développer les abréviations pour les adresses IRI et les motifs de triplet données à la section 4.

La clause WhereClause est constituée d'un motif GroupGraphPattern comprenant les formes suivantes :

Chacune est traduite selon la procédure suivante :

Transform(forme syntaxique)

S'il s'agit de la forme TriplesBlock

Le résultat est BGP(liste de motifs de triplet)

S'il s'agit de la forme GroupOrUnionGraphPattern

Soit A := non défini

Pour chaque élément G dans le GroupOrUnionGraphPattern
    Si A n'est pas défini
        A := Transform(G)
    Sinon
        A := Union(A, Transform(G))

Le résultat est A

S'il s'agit de la forme GraphGraphPattern

Si la forme est GRAPH IRI GroupGraphPattern
    Le résultat est Graph(IRI, Transform(GroupGraphPattern))
Si la forme est GRAPH Var GroupGraphPattern
    Le résultat est Graph(Var, Transform(GroupGraphPattern))

S'il s'agit de la forme GroupGraphPattern

Nous introduisons les symboles suivants :

Soit FS := l'ensemble vide
Soit G  := le motif vide, Z, un motif de graphe élémentaire qui est l'ensemble vide.

Pour chaque élément E dans le motif GroupGraphPattern
   Si E est de la forme FILTER(expr)
       FS := FS set-union {expr}
   Si E est de la forme OPTIONAL{P}
   Alors
       Soit A := Transform(P)
       Si A est de la forme Filter(F, A2)
           G := LeftJoin(G, A2, F)
       sinon 
           G := LeftJoin(G, A, true)
   Si E est d'une autre forme :
      Soit A := Transform(E)
      G := Join(G, A)
   
  
Si FS n'est pas vide :
  Soit X := Conjonction des expressions dans FS
  G := Filter(X, G)

Le résultat est G.

Étape de simplification :

Les groupes d'un seul motif de graphe (pas un filtre) deviennent Join(Z, A) et peuvent être remplacés par A. Le motif de graphe vide Z est l'identité pour Join :

Remplacer Join(Z, A) par A
Remplacer Join(A, Z) par A

12.2.2 Exemples de motifs de graphe convertis

La deuxième forme d'un exemple de récriture équivaut à la première, car l'étape de simplification supprime les jointures (joins) de groupe vide.

Exemple de groupe avec un motif de graphe élémentaire consistant en un seul motif de triplet :

{ ?s ?p ?o }
Join(Z, BGP(?s ?p ?o) )
BGP(?s ?p ?o)

Exemple de groupe avec un motif de graphe élémentaire consistant en deux motifs de triplet :

{ ?s :p1 ?v1 ; :p2 ?v2 }
BGP( ?s :p1 ?v1 .?s :p2 ?v2 )

Exemple de groupe consistant en l'union de deux motifs de graphe élémentaires :

{ { ?s :p1 ?v1 } UNION {?s :p2 ?v2 } }
Union(Join(Z, BGP(?s :p1 ?v1)),
      Join(Z, BGP(?s :p2 ?v2)) )
Union( BGP(?s :p1 ?v1) , BGP(?s :p2 ?v2) )

Exemple de groupe consistant en l'union d'une union et d'un motif de graphe élémentaire :

{ { ?s :p1 ?v1 } UNION {?s :p2 ?v2 } UNION {?s :p3 ?v3 } }
Union(
    Union( Join(Z, BGP(?s :p1 ?v1)),
           Join(Z, BGP(?s :p2 ?v2))) ,
    Join(Z, BGP(?s :p3 ?v3)) )
Union(
    Union( BGP(?s :p1 ?v1) ,
           BGP(?s :p2 ?v2),
    BGP(?s :p3 ?v3))

Exemple de groupe consistant en un motif de graphe élémentaire et un motif de graphe optionnel :

{ ?s :p1 ?v1 OPTIONAL {?s :p2 ?v2 } }
LeftJoin(
    Join(Z, BGP(?s :p1 ?v1)),
    Join(Z, BGP(?s :p2 ?v2)) ),
    true)
LeftJoin(BGP(?s :p1 ?v1), BGP(?s :p2 ?v2), true)

Exemple de groupe consistant en un motif de graphe élémentaire et deux motifs de graphe optionnels :

{ ?s :p1 ?v1 OPTIONAL {?s :p2 ?v2 } OPTIONAL { ?s :p3 ?v3 } }
LeftJoin(
    LeftJoin(
        BGP(?s :p1 ?v1),
        BGP(?s :p2 ?v2),
        true) ,
    BGP(?s :p3 ?v3),
    true)

Exemple de groupe consistant en un motif de graphe élémentaire et un motif de graphe optionnel avec un filtre :

{ ?s :p1 ?v1 OPTIONAL {?s :p2 ?v2 FILTER(?v1<3) } }
LeftJoin(
     Join(Z, BGP(?s :p1 ?v1)),
     Join(Z, BGP(?s :p2 ?v2)),
     (?v1<3) )
LeftJoin(
    BGP(?s :p1 ?v1) ,
    BGP(?s :p2 ?v2) ,
   (?v1<3) )

Exemple de groupe consistant en l'union d'un motif de graphe élémentaire et d'un motif de graphe optionnel :

{ {?s :p1 ?v1} UNION {?s :p2 ?v2} OPTIONAL {?s :p3 ?v3} }
LeftJoin(
  Union(BGP(?s :p1 ?v1),
        BGP(?s :p2 ?v2)) ,
  BGP(?s :p3 ?v3) ,
  true )

Exemple de groupe consistant en un motif de graphe élémentaire, un filtre et un motif de graphe optionnel :

{ ?s :p1 ?v1 FILTER (?v1 < 3 ) OPTIONAL {?s :p2 ?v2} } }
Filter( ?v1 < 3 ,
  LeftJoin( BGP(?s :p1 ?v1), BGP(?s :p2 ?v2), true) ,
  )

12.2.3 Conversion des modificateurs de solution

Étape 1 : ToList

ToList transforme un multiensemble (multiset) en une séquence avec les mêmes éléments et la même cardinalité. Il n'y a aucun tri implicite de la séquence ; les doubles n'ont pas besoin d'être adjacents.

Soit M := ToList(Pattern)

Étape 2 : ORDER BY

Si la chaîne d'interrogation a une clause ORDER BY

M := OrderBy(M, liste de comparateurs de tri)

Étape 3 : Projection

M := Project(M, vars)

où vars est l'ensemble des variables mentionnées dans la clause SELECT, ou de toutes les variables nommées dans l'interrogation si SELECT * est utilisé.

Étape 4 : DISTINCT

Si l'interrogation contient DISTINCT,

M := Distinct(M)

Étape 5 : REDUCED

Si l'interrogation contient REDUCED,

M := Reduced(M)

Étape 6 : OFFSET et LIMIT

Si l'interrogation contient "OFFSET start" ou "LIMIT length"

M := Slice(M, start, length)

par défaut, start vaut 0

par défaut, length vaut (size(M)-start).

L'interrogation abstraite globale est M.

12.3 Motifs de graphe élémentaires

Lors de la comparaison de motifs de graphe, les solutions possibles forment un multiensemble [Multiset], appelé aussi sac (bag). Un multiensemble est une collection non ordonnée d'éléments dans lequel chaque élément peut apparaître plus d'une fois. Il est décrit par un ensemble d'éléments et une fonction de cardinalité donnant le nombre d'apparitions (ou multiplicité) de chaque élément de l'ensemble dans le multiensemble.

Notons μ les applications de solution et

Notons μ0 l'application telle que dom(μ0) est l'ensemble vide.

Notons Ω0 le multiensemble constitué exactement de l'application vide μ0, avec une multiplicité de 1. C'est l'identité de jointure.

Notons μ(?x→t) la solution associant la variable x au terme RDF t : { (x, t) }

Notons Ω(?x→t) le multiensemble constitué exactement de μ(?x→t), c'est-à-dire { { (x, t) } } avec une multiplicité de 1.

Définition : applications compatibles (compatible mappings)

Deux applications de solution μ1 et μ2 sont compatibles si, pour toute variable v dans dom(μ1) et dans dom(μ2), μ1(v) = μ2(v).

Si μ1 et μ2 sont compatibles, alors μ1 set-union μ2 est aussi une application. Notons merge(μ1, μ2) pour μ1 set-union μ2

Notons card[Ω](μ) la multiplicité de l'application de solution μ dans un multiensemble d'applications Ω.

12.3.1 Concordance des motifs de graphe élémentaires SPARQL

Les motifs de graphe élémentaires forment la base du filtrage par motif de SPARQL. Un motif de graphe élémentaire est comparé au graphe actif de cette partie de l'interrogation. Les motifs de graphe élémentaires peuvent être instanciés en remplaçant les variables et les nœuds anonymes par des termes, en donnant deux notions de l'instance. Les nœuds anonymes sont remplacés en utilisant une application d'instance RDF,  σ, des nœuds anonymes aux termes RDF ; les variables sont remplacées par une application de solution, des variables d'interrogation aux termes RDF.

Définition : application d'instance de motif (pattern instance mapping)

Une application d'instance de motif, P, est la combinaison d'une application d'instance RDF, σ, et d'une application de solution, μ, telle que P(x) = μ(σ(x))

Toute application d'instance de motif définit une application de solution unique et une application d'instance RDF unique, obtenue en la restreignant respectivement aux variables d'interrogation et aux nœuds anonymes.

Définition : concordance d'un motif de graphe élémentaire (basic graph pattern matching)

Soit BGP un motif de graphe élémentaire et G un graphe RDF.

μ est une solution pour BGP de G lorsqu'il existe une application d'instance de motif P telle que P(BGP) soit un sous-graphe de G et μ soit la restriction de P aux variables d'interrogation dans BGP.

card[Ω](μ) = card[Ω](nombre d'applications d'instance RDF, σ, tel que P = μ(σ) soit une application d'instance de motif et P(BGP) soit un sous-graphe de G).

Si un motif de graphe élémentaire est l'ensemble vide, alors la solution est Ω0.

12.3.2 Traitement des nœuds anonymes

Cette définition permet à l'application de solution de relier une variable dans un motif de graphe élémentaire, BGP, à un nœud anonyme dans G. Puisque SPARQL traite les identificateurs de nœud anonyme dans un document au format XML des résultats d'interrogation SPARQL comme étant confinés (scoped) au document, on ne peut pas les prendre comme nœuds identifiants dans le graphe actif de l'ensemble de données. Si nous notons DS l'ensemble de données d'une interrogation, les solutions des graphes sont donc comprises comme n'appartenant pas au graphe actif de DS même mais à un graphe RDF appelé le « graphe de visibilité » (scoping graph), qui est le graphe équivalent du graphe actif de DS mais ne partage pas de nœuds anonymes avec DS ou avec BGP. Le même graphe de visibilité est utilisé pour toutes les solutions d'une seule interrogation. Le graphe de visibilité est une construction purement théorique ; en pratique, l'effet est obtenu simplement par les conventions de visibilité de document des identificateurs de nœud anonyme.

Comme les nœuds anonymes RDF admettent une infinité de solutions redondantes pour plusieurs motifs, il peut y avoir une infinité de solutions de motif (obtenues en remplaçant les nœuds anonymes par des nœuds anonymes différents). Il est donc nécessaire de délimiter en quelque sorte les solutions d'un motif de graphe élémentaire. SPARQL utilise le critère de concordance de sous-graphe (subgraph match criterion) pour déterminer les solutions d'un motif de graphe élémentaire. Il y a une seule solution pour chaque application d'instance de motif distincte, du motif de graphe élémentaire à un sous-ensemble du graphe actif.

On l'optimise pour faciliter le calcul plutôt que pour éliminer la redondance. Cela autorise les résultats d'interrogation à contenir des redondances, même si le graphe actif de l'ensemble de données est mince (lean), et des ensembles de données logiquement équivalents à produire des résultats d'interrogation différents.

12.4 Algèbre SPARQL

Pour chaque symbole d'une interrogation abstraite SPARQL, nous définissons un opérateur d'évaluation. Nous utilisons les opérateurs algébriques SPARQL de même nom pour évaluer les nœuds des interrogations abstraites SPARQL comme cela est décrit à la section 12.5 Sémantique d'évaluation SPARQL.

Définition : Filter

Soit Ω un multiensemble d'applications de solution et expr une expression. Nous définissons :

Filter(expr, Ω) = { μ | μ dans Ω et expr(μ) est une expression qui a une valeur booléenne effective de true }

card[Filter(expr, Ω)](μ) = card[Ω](μ)

Définition : Join

Soit Ω1 et Ω2 des multiensembles d'applications de solution. Nous définissons :

Join(Ω1, Ω2) = { merge(μ1, μ2) | μ1 dans Ω1 et μ2 dans Ω2, et μ1 et μ2 étant compatibles }

card[Join(Ω1, Ω2)](μ) =
    pour chaque merge(μ1, μ2), μ1 dans Ω1 et μ2 dans Ω2 tel que μ = merge(μ1, μ2),
        somme de (μ1, μ2), card[Ω1](μ1)*card[Ω2](μ2)

Il est possible qu'une application de solution μ dans une jointure (Join) puisse apparaître dans des applications de solution différentes, μ1 et μ2 dans les multiensembles étant joints. La multiplicité (cardinality) de μ est la somme des multiplicités de toutes les possibilités.

Définition : Diff

Soit Ω1 et Ω2 des multiensembles d'applications de solution. Nous définissons :

Diff(Ω1, Ω2, expr) = { μ | μ dans Ω1 tel que pour tous les μ′ dans Ω2, soit μ et μ′ ne sont pas compatibles, soit μ et μ' sont compatibles et expr(merge(μ, μ')) a une valeur booléenne effective de false }

card[Diff(Ω1, Ω2, expr)](μ) = card[Ω1](μ)

Diff est utilisé en interne pour la définition de LeftJoin.

Définition : LeftJoin

Soit Ω1 et Ω2 des multiensembles d'applications de solution et expr une expression. Nous définissons :

LeftJoin(Ω1, Ω2, expr) = Filter(expr, Join(Ω1, Ω2)) set-union Diff(Ω1, Ω2, expr)

card[LeftJoin(Ω1, Ω2, expr)](μ) = card[Filter(expr, Join(Ω1, Ω2))](μ) + card[Diff(Ω1, Ω2, expr)](μ)

Qui s'écrit en entier :

LeftJoin(Ω1, Ω2, expr) =
    { merge(μ1, μ2) | μ1 dans Ω1 et μ2 dans Ω2, et μ1 et μ2 sont compatibles et expr(merge(μ1, μ2)) est true }
set-union
    { μ1 | μ1 dans Ω1 et μ2 dans Ω2, et μ1 et μ2 ne sont pas compatibles }
set-union
    { μ1 | μ1 dans Ω1 et μ2 dans Ω2, et μ1 et μ2 sont compatibles et expr(merge(μ1, μ2)) est false }

Comme ceux-ci sont distincts, la multiplicité de LeftJoin est la multiplicité de ces composants individuels de la définition.

Définition : Union

Soit Ω1 et Ω2 des multiensembles d'applications de solution. Nous définissons :

Union(Ω1, Ω2) = { μ | μ dans Ω1 ou μ dans Ω2 }

card[Union(Ω1, Ω2)](μ) = card[Ω1](μ) + card[Ω2](μ)

Notons [x | C] une suite d'éléments où C(x) est true.

Notons card[L](x) comme étant la multiplicité de x dans L.

Définition : ToList

Soit Ω un multiensemble d'applications de solution. Nous définissons :

ToList(Ω) = une suite d'applications μ dans Ω dans un ordre quelconque, avec card[Ω](μ) apparitions de μ

card[ToList(Ω)](μ) = card[Ω](μ)

Définition : OrderBy

Soit Ψ une suite d'applications de solution. Nous définissons :

OrderBy(Ψ, condition) = [ μ | μ dans Ψ et la suite satisfait à la condition de tri]

card[OrderBy(Ψ, condition)](μ) = card[Ψ](μ)

Définition : Project

Soit Ψ une suite d'applications de solution et PV un ensemble de variables.

Pour l'application μ, notons Proj(μ, PV) la restriction de μ aux variables dans PV.

Project(Ψ, PV) = [ Proj(Ψ[μ], PV) | μ dans Ψ ]

card[Project(Ψ, PV)](μ) = card[Ψ](μ)

L'ordre de Project(Ψ, PV) doit conserver un tri donné par OrderBy.

Définition : Distinct

Soit Ψ une suite d'applications de solutions. Nous définissons :

Distinct(Ψ) = [ μ | μ dans Ψ ]

card[Distinct(Ψ)](μ) = 1

L'ordre de Distinct(Ψ) doit conserver un tri donné par OrderBy.

Définition : Reduced

Soit Ψ une suite d'applications de solution. Nous définissons :

Reduced(Ψ) = [ μ | μ dans Ψ ]

card[Reduced(Ψ)](μ) est entre 1 et card[Ψ](μ)

L'ordre de Reduced(Ψ) doit conserver un tri donné par OrderBy.

Le modificateur de séquence de solution Reduced ne garantit pas de multiplicité définie.

Définition : Slice

Soit Ψ une suite d'applications de solution. Nous définissons :

Slice(Ψ, start, length)[i] = Ψ[start+i] pour i = 0 jusqu'à (length-1)

12.5 Sémantique d'évaluation SPARQL

Nous définissons eval(D(G), motif de graphe) comme étant l'évaluation d'un motif de graphe par rapport à un ensemble de données D ayant un graphe actif G. Le graphe actif est initialement le graphe par défaut.

D         : un ensemble de données
D(G)      : D un ensemble de données avec un graphe actif G (celui auquel les motifs sont comparés)
D[i]      : le graphe d'adresse IRI i dans l'ensemble de données D
D[DFT]    : le graphe par défaut de D
P, P1, P2 : des motifs de graphe
L         : une séquence de solutions
Définition : évaluation de Filter(F, P)
eval(D(G), Filter(F, P)) = Filter(F, eval(D(G),P))
Définition : évaluation de Join(P1, P2)
eval(D(G), Join(P1, P2)) = Join(eval(D(G), P1), eval(D(G), P2))
Définition : évaluation de LeftJoin(P1, P2, F)
eval(D(G), LeftJoin(P1, P2, F)) = LeftJoin(eval(D(G), P1), eval(D(G), P2), F)
Définition : évaluation d'un motif de graphe élémentaire
eval(D(G), BGP) = multiensemble d'applications de solution

Cf. la section 12.3 Motifs de graphe élémentaires

Définition : évaluation d'un motif d'union
eval(D(G), Union(P1,P2)) = Union(eval(D(G), P1), eval(D(G), P2))
Définition : évaluation d'un motif de graphe
si IRI est un nom de graphe dans D
eval(D(G), Graph(IRI,P)) = eval(D(D[IRI]), P)
si IRI n'est pas un nom de graphe dans D
eval(D(G), Graph(IRI,P)) = le multiensemble vide
eval(D(G), Graph(var,P)) =
     Soit R le multiensemble vide
     foreach IRI i in D
        R := Union(R, Join( eval(D(D[i]), P) , Ω(?var→i) )
     le résultat est R

L'évaluation d'un graphe utilise l'opérateur d'union de l'algèbre SPARQL. La multiplicité d'une application de solution est la somme des multiplicités de cette application de solution dans chaque opération de jointure (join).

Définition : évaluation de ToList
eval(D, ToList(P)) = ToList(eval(D(D[DFT]), P))
Définition : évaluation de Distinct
eval(D, Distict(L)) = Distinct(eval(D, L))
Définition : évaluation de Reduced
eval(D, Reduced(L)) = Reduced(eval(D, L))
Définition : évaluation de Project
eval(D, Project(L, vars)) = Project(eval(D, L), vars)
Définition : évaluation de OrderBy
eval(D, OrderBy(L, condition)) = OrderBy(eval(D, L), condition)
Définition : évaluation de Slice
eval(D, Slice(L, start, length)) = Slice(eval(D, L), start, length)

12.6 Extension de la concordance des graphes élémentaires SPARQL

On peut utiliser la conception SPARQL globale pour des interrogations supposant une forme plus élaborée d'inférence (entailment) que l'inférence simple, en récrivant les conditions de concordance des motifs de graphe élémentaires. Puisqu'énoncer de telles conditions dans une seule forme générale, qui s'applique à toutes les formes d'inférence et élimine de façon optimale la redondance inutile ou inappropriée, est un problème de recherche ouvert, ce document donne seulement les conditions nécessaires auxquelles une telle solution devrait satisfaire. Celles-ci devront être développées en définitions complètes pour chaque cas particulier.

Les motifs de graphe élémentaires se tiennent dans une même relation vis-à-vis des motifs de triplet que les motifs RDF vis-à-vis des triplets RDF, et une bonne partie de la même terminologie peut s'y appliquer. En particulier, deux motifs de graphe élémentaires sont dits équivalents s'il existe une bijection M entre les termes des motifs de triplet qui relie les nœuds anonymes aux nœuds anonymes et relie les variables, les littéraux et les adresses IRI à eux-mêmes, de telle sorte qu'un triplet ( s, p, o ) se trouve dans le premier motif si et seulement si le triplet ( M(s), M(p), M(o) ) se trouve dans le deuxième. Cette définition étend celle de l'équivalence des graphes RDF aux motifs de graphe élémentaires en préservant les noms des variables à travers les motifs équivalents.

Un régime d'inférence (entailment regime) définit :

  1. un sous-ensemble de graphes RDF dits bien formés (well-formed) pour le régime ;
  2. une relation d'inférence entre des sous-ensembles de graphes bien formés et des graphes bien formés.

Les exemples de régimes d'inférence comprennent l'inférence simple [RDF-MT], l'inférence RDF [RDF-MT], l'inférence RDFS [RDF-MT], la D-inférence (D-entailment) [RDF-MT] et l'inférence OWL-DL [OWL-Semantics]. Parmi celles-ci, seule l'inférence OWL-DL restreint l'ensemble des graphes bien formés. Si E est un régime d'inférence, alors nous nous référerons à une E-inférence, une E-cohérence, etc. en suivant cette convention d'écriture.

Certains régimes d'inférence peuvent catégoriser des graphes RDF comme étant incohérents. Par exemple, le graphe RDF suivant :

_:x rdf:type xsd:string .
_:x rdf:type xsd:decimal .

est D-incohérent lorsque D contient les types de données XSD. L'effet d'une interrogation sur un graphe incohérent n'est pas couvert par cette spécification, mais l'extension SPARQL particulière doit le définir.

Une extension SPARQL d'une E-inférence doit satisfaire aux conditions suivantes :

  1. Le graphe de visibilité SG correspondant à un graphe actif cohérent AG est défini exclusivement et est E-équivalent à AG ;

  2. Pour tout motif de graphe élémentaire BGP et toute application de solution de graphe P, P(BGP) est bien formée pour E ;

  3. Pour tout graphe de visibilité SG et tout ensemble de réponses {P1 ... Pn} pour un motif de graphe élémentaire BGP, où {BGP1 .... BGPn} est un ensemble de motifs de graphe élémentaires, tous équivalents à BGP, aucun d'eux ne partagent de nœuds anonymes avec un autre ou avec SG ;

    SG E-infère (SG union P1(BGP1) union ... union Pn(BGPn))

    Ces conditions ne déterminent pas complètement l'ensemble des réponses possibles, puisque RDF autorise une quantité illimitée de redondance. De ce fait, la condition suivante doit en outre être vérifiée ;

  4. Chaque extension SPARQL doit fournir des conditions sur les ensembles de réponses garantissant que tous les BGP et AG ont un ensemble fini de réponses qui est unique jusque dans l'équivalence des graphes RDF.

Remarques

(a) SG sera souvent équivalent (graphe) à AG, mais le restreindre à une E-équivalence permet d'appliquer certaines formes de normalisation, par exemple l'élimination des redondances sémantiques, aux documents sources avant l'interrogation.

(b) La construction dans la condition 3 assure que tous les nœuds anonymes introduits par l'application de solution sont utilisés en interne d'une façon cohérente à celle dont les nœuds anonymes apparaissent dans SG. On s'assure que les identificateurs de nœuds anonymes apparaissent dans plus d'une réponse dans un ensemble de réponses seulement lorsque les nœuds anonymes identifiés ainsi sont en effet identiques dans SG. Si l'extension ne permet pas les liaisons de réponses aux nœuds anonymes, alors on peut simplifier cette condition en la suivante :

SG E-infère P(BGP) pour chaque solution de motif P.

(c) Ces conditions n'imposent pas l'obligation SPARQL selon laquelle SG ne doit pas partager de nœuds anonymes avec AG ou BGP. En particulier, cela permet à SG d'être en fait AG. Cela autorise des protocoles d'interrogation dans lesquels les identificateurs de nœuds anonymes gardent leur signification entre l'interrogation et le document source, ou à travers plusieurs interrogations. De tels protocoles ne sont toutefois pas gérés par la spécification de protocole SPARQL courante.

(d) Puisque les conditions 1 à 3 ne sont nécessaires que sur les réponses, la condition 4 autorise des cas où l'ensemble des réponses légales peut être restreint de diverses façons. Par exemple, l'état de l'art actuel en matière d'interrogation OWL-DL se concentre sur le cas où les liaisons de réponses aux nœuds anonymes sont prohibées. Nous notons que ces conditions permettent même le cas pathologique « muet » où chaque interrogation a un ensemble de réponses vide.

(e) Aucune de ces conditions ne mentionne explicitement les applications d'instance sur les nœuds anonymes dans BGP. Pour certains régimes d'inférence, l'interprétation existentielle des nœuds anonymes ne peut pas être entièrement capturée par l'existence d'une seule application d'instance. Ces conditions permettent à de tels régimes de donner aux nœuds anonymes dans les motifs d'interrogation une lecture « entièrement existentielle ».

On montre aisément que SPARQL satisfait à ces conditions dans le cas où E est une inférence simple, étant donné que la condition SPARQL sur SG est qu'il équivaut (graphe) à AG mais ne partage pas de nœuds anonymes avec AG ou BGP (ce qui satisfait à la première condition). Seule la condition 3 n'est pas évidente.

Chaque réponse Pi est la restriction d'application de solution d'une instance SPARQL Mi, telle que Mi(BGPi) est un sous-graphe de SG. Puisque BGPi et SG n'ont aucun nœud anonyme commun, le domaine d'arrivée (range) de Mi ne contient aucun nœud anonyme de BGPi ; ainsi, les composantes d'application de solution Pi et d'application d'instance RDF Ii de Mi se substituent, et Mi(BGPi) = Ii(Pi(BGPi)). Donc :

M1(BGP1) union ... union Mn(BGPn)
= I1(P1(BGP1)) union ... union In(Pn(BGPn))
= [ I1 + ... + In]( P1(BGP1) union ... union Pn(BGPn) )

puisque les domaines de définition (domains) des applications d'instance Ii sont tous mutuellement exclusifs. Comme ils sont également exclusif par rapport à SG,

SG union [ I1 + ... + In]( P1(BGP1) union ... union Pn(BGPn) )
= [ I1 + ... + In](SG union P1(BGP1) union ... union Pn(BGPn) )

c'est-à-dire que

SG union P1(BGP1) union ... union Pn(BGPn)

a une instance laquelle est un sous-graphe de SG, et est donc inférée simplement par SG selon le lemme d'interpolation RDF [RDF-MT].

A. Grammaire SPARQL

A.1 Chaîne d'interrogation SPARQL

Une chaîne d'interrogation SPARQL (SPARQL query string) est une chaîne de caractères Unicode (cf. la section 6.1 Concepts de chaînes de [CHARMOD]) dans le langage défini par la grammaire suivante, commençant par la production Query. Pour la compatibilité avec des versions futures d'Unicode, les caractères dans cette chaîne peuvent inclure des points de code Unicode non affectés à la date de cette publication (cf. la section 4 Pattern Syntax dans Identifier and Pattern Syntax [UNIID]). Pour les productions excluant des classes de caractères (par exemple [^<>'{}|^`]), les caractères sont exclus de l'intervalle #x0 - #x10FFFF.

A.2 Séquences d'échappement des points de code

Les séquences d'échappement de points de code d'une chaîne d'interrogation SPARQL sont traitées avant l'analyse selon la grammaire de la définition EBNF ci-dessous. Les séquences d'échappement de points de code d'une chaîne d'interrogation SPARQL sont les suivantes :

Échappement Point de code Unicode
'\u' HEX HEX HEX HEX Un point de code Unicode dans l'intervalle U+0 à U+FFFF inclus correspondant à la valeur hexadécimale codée.
'\U' HEX HEX HEX HEX HEX HEX HEX HEX Un point de code Unicode dans l'intervalle U+0 à U+10FFFF inclus correspondant à la valeur hexadécimale codée.

HEX est un caractère hexadécimal.

HEX ::= [0-9] | [A-F] | [a-f]

Exemples :

<ab\u00E9xy>        # le point de code 0x00E9 est la LETTRE MINUSCULE LATINE E ACCENT AIGU é
\u03B1:a            # le point de code 0x03B1 est la LETTRE MINUSCULE GRECQUE ALPHA α
a\u003Ab            # a:b -- le point de code 0x003A est le DEUX-POINTS

Les séquences d'échappement de points de code peuvent apparaître n'importe où dans la chaîne d'interrogation. Elles sont traitées avant l'analyse fondée sur les règles de grammaire et peuvent donc être remplacées par des points de code ayant une signification dans la grammaire, ainsi ":" qui marque un nom préfixé.

Ces séquences d'échappement ne sont pas incluses dans la grammaire ci-dessous. Seules les séquences d'échappement de caractères qui seraient légales à ce point dans la grammaire peuvent être données. Par exemple, la variable "?x\u0020y" n'est pas légale (\u0020 est un caractère ESPACE non admis dans un nom de variable).

A.3 Caractères blancs

Les caractères blancs (white space) — production WS — servent à séparer deux terminaux qui seraient sinon (mal) interprétés comme un seul. Les noms de règle en majuscules ci-dessous indiquent où les caractères blancs sont signficatifs ; ceux-ci forment un choix de terminaux possible pour construire un analyseur SPARQL. Les caractères blancs sont significatifs dans les chaînes.

Par exemple :

?a<?b&&?c>?d

est la variable de séquence d'atome '?a', une adresse IRI '<?b&&?c>' et une variable '?d', et non une expression impliquant l'opérateur '&&' connectant deux expressions avec '<' (inférieur à) et '>' (supérieur à).

A.4 Commentaires

Les commentaires dans les interrogations SPARQL prennent la forme d'un caractère "#", hors d'une adresse IRI ou d'une chaîne, et continuent jusqu'à la fin de la ligne (marquée par un caractère 0x0D ou 0x0A) ou à la fin du fichier s'il n'y a pas de caractère de fin de ligne après le marqueur de commentaire. Les commentaires sont traités comme des caractères blancs.

A.5 Références IRI

Le texte filtré par la production IRI_REF et la production PrefixedName (après expansion du préfixe), après le traitement des échappements, doit être conforme à la syntaxe générique des références IRI à la section 2.2 Définition ABNF des références IRI et des adresses IRI du RFC 3987 [RFC3987]. Par exemple, la référence IRI_REF <abc#def> peut apparaître dans une chaîne d'interrogation SPARQL, mais la référence IRI_REF <abc##def> ne le doit pas.

Les adresses IRI de base déclarées avec le mot-clé BASE doivent être des adresses IRI absolues. Un préfixe déclaré avec le mot-clé PREFIX ne peut pas être redéclaré dans la même interrogation. Cf. la section 2.1.1 Syntaxe des termes IRI pour une description de BASE et de PREFIX.

A.6 Étiquettes de nœuds anonymes

La même étiquette de nœud anonyme ne peut pas être utilisée dans deux motifs de graphes élémentaires distincts avec la même interrogation.

A.7 Séquences d'échappement dans les chaînes

En plus des séquences d'échappement de points de code, il y a les séquences d'échappement suivantes dans toute production string (par exemple STRING_LITERAL1, STRING_LITERAL2, STRING_LITERAL_LONG1, STRING_LITERAL_LONG2) :

Échappement Point de code Unicode
'\t' U+0009 (TABULATION HORIZONTALE)
'\n' U+000A (CHANGEMENT DE LIGNE)
'\r' U+000D (RETOUR DE CHARIOT)
'\b' U+0008 (ESPACE ARRIÈRE)
'\f' U+000C (SAUT DE PAGE)
'\"' U+0022 (GUILLEMET ANGLAIS)
"\'" U+0027 (APOSTROPHE)
'\\' U+005C (BARRE OBLIQUE INVERSÉE)

Exemples :

"abc\n"
"xy\rz"
'xy\tz'

A.8 Grammaire

La notation EBNF utilisée dans la grammaire est défini à la section 6 Notation de la spécification Langage de balisage extensible (XML) 1.1 [XML11].

Les mots-clés sont comparés d'une manière indépendante de la casse à l'exception du mot-clé 'a' qui est utilisé, en accord avec Turtle et N3, en place de l'adresse IRI de rdf:type (en entier, http://www.w3.org/1999/02/22-rdf-syntax-ns#type).

Mots-clés :

BASE SELECT ORDER BY FROM GRAPH STR isURI
PREFIX CONSTRUCT LIMIT FROM NAMED OPTIONAL LANG isIRI
  DESCRIBE OFFSET WHERE UNION LANGMATCHES isLITERAL
  ASK DISTINCT   FILTER DATATYPE REGEX
    REDUCED   a BOUND true
          sameTERM false

Les séquences d'échappement sont dépendantes de la casse.

Lors du choix d'une règle à appliquer, la correspondance la plus longue est choisie.

[1]   Query   ::=   Prologue
( SelectQuery | ConstructQuery | DescribeQuery | AskQuery )
[2]   Prologue   ::=   BaseDecl? PrefixDecl*
[3]   BaseDecl   ::=   'BASE' IRI_REF
[4]   PrefixDecl   ::=   'PREFIX' PNAME_NS IRI_REF
[5]   SelectQuery   ::=   'SELECT' ( 'DISTINCT' | 'REDUCED' )? ( Var+ | '*' ) DatasetClause* WhereClause SolutionModifier
[6]   ConstructQuery   ::=   'CONSTRUCT' ConstructTemplate DatasetClause* WhereClause SolutionModifier
[7]   DescribeQuery   ::=   'DESCRIBE' ( VarOrIRIref+ | '*' ) DatasetClause* WhereClause? SolutionModifier
[8]   AskQuery   ::=   'ASK' DatasetClause* WhereClause
[9]   DatasetClause   ::=   'FROM' ( DefaultGraphClause | NamedGraphClause )
[10]   DefaultGraphClause   ::=   SourceSelector
[11]   NamedGraphClause   ::=   'NAMED' SourceSelector
[12]   SourceSelector   ::=   IRIref
[13]   WhereClause   ::=   'WHERE'? GroupGraphPattern
[14]   SolutionModifier   ::=   OrderClause? LimitOffsetClauses?
[15]   LimitOffsetClauses   ::=   ( LimitClause OffsetClause? | OffsetClause LimitClause? )
[16]   OrderClause   ::=   'ORDER' 'BY' OrderCondition+
[17]   OrderCondition   ::=   ( ( 'ASC' | 'DESC' ) BrackettedExpression )
| ( Constraint | Var )
[18]   LimitClause   ::=   'LIMIT' INTEGER
[19]   OffsetClause   ::=   'OFFSET' INTEGER
[20]   GroupGraphPattern   ::=   '{' TriplesBlock? ( ( GraphPatternNotTriples | Filter ) '.'? TriplesBlock? )* '}'
[21]   TriplesBlock   ::=   TriplesSameSubject ( '.' TriplesBlock? )?
[22]   GraphPatternNotTriples   ::=   OptionalGraphPattern | GroupOrUnionGraphPattern | GraphGraphPattern
[23]   OptionalGraphPattern   ::=   'OPTIONAL' GroupGraphPattern
[24]   GraphGraphPattern   ::=   'GRAPH' VarOrIRIref GroupGraphPattern
[25]   GroupOrUnionGraphPattern   ::=   GroupGraphPattern ( 'UNION' GroupGraphPattern )*
[26]   Filter   ::=   'FILTER' Constraint
[27]   Constraint   ::=   BrackettedExpression | BuiltInCall | FunctionCall
[28]   FunctionCall   ::=   IRIref ArgList
[29]   ArgList   ::=   ( NIL | '(' Expression ( ',' Expression )* ')' )
[30]   ConstructTemplate   ::=   '{' ConstructTriples? '}'
[31]   ConstructTriples   ::=   TriplesSameSubject ( '.' ConstructTriples? )?
[32]   TriplesSameSubject   ::=   VarOrTerm PropertyListNotEmpty | TriplesNode PropertyList
[33]   PropertyListNotEmpty   ::=   Verb ObjectList ( ';' ( Verb ObjectList )? )*
[34]   PropertyList   ::=   PropertyListNotEmpty?
[35]   ObjectList   ::=   Object ( ',' Object )*
[36]   Object   ::=   GraphNode
[37]   Verb   ::=   VarOrIRIref | 'a'
[38]   TriplesNode   ::=   Collection | BlankNodePropertyList
[39]   BlankNodePropertyList   ::=   '[' PropertyListNotEmpty ']'
[40]   Collection   ::=   '(' GraphNode+ ')'
[41]   GraphNode   ::=   VarOrTerm | TriplesNode
[42]   VarOrTerm   ::=   Var | GraphTerm
[43]   VarOrIRIref   ::=   Var | IRIref
[44]   Var   ::=   VAR1 | VAR2
[45]   GraphTerm   ::=   IRIref | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | NIL
[46]   Expression   ::=   ConditionalOrExpression
[47]   ConditionalOrExpression   ::=   ConditionalAndExpression ( '||' ConditionalAndExpression )*
[48]   ConditionalAndExpression   ::=   ValueLogical ( '&&' ValueLogical )*
[49]   ValueLogical   ::=   RelationalExpression
[50]   RelationalExpression   ::=   NumericExpression ( '=' NumericExpression | '!=' NumericExpression | '<' NumericExpression | '>' NumericExpression | '<=' NumericExpression | '>=' NumericExpression )?
[51]   NumericExpression   ::=   AdditiveExpression
[52]   AdditiveExpression   ::=   MultiplicativeExpression ( '+' MultiplicativeExpression | '-' MultiplicativeExpression | NumericLiteralPositive | NumericLiteralNegative )*
[53]   MultiplicativeExpression   ::=   UnaryExpression ( '*' UnaryExpression | '/' UnaryExpression )*
[54]   UnaryExpression   ::=     '!' PrimaryExpression
| '+' PrimaryExpression
| '-' PrimaryExpression
| PrimaryExpression
[55]   PrimaryExpression   ::=   BrackettedExpression | BuiltInCall | IRIrefOrFunction | RDFLiteral | NumericLiteral | BooleanLiteral | Var
[56]   BrackettedExpression   ::=   '(' Expression ')'
[57]   BuiltInCall   ::=     'STR' '(' Expression ')'
| 'LANG' '(' Expression ')'
| 'LANGMATCHES' '(' Expression ',' Expression ')'
| 'DATATYPE' '(' Expression ')'
| 'BOUND' '(' Var ')'
| 'sameTerm' '(' Expression ',' Expression ')'
| 'isIRI' '(' Expression ')'
| 'isURI' '(' Expression ')'
| 'isBLANK' '(' Expression ')'
| 'isLITERAL' '(' Expression ')'
| RegexExpression
[58]   RegexExpression   ::=   'REGEX' '(' Expression ',' Expression ( ',' Expression )? ')'
[59]   IRIrefOrFunction   ::=   IRIref ArgList?
[60]   RDFLiteral   ::=   String ( LANGTAG | ( '^^' IRIref ) )?
[61]   NumericLiteral   ::=   NumericLiteralUnsigned | NumericLiteralPositive | NumericLiteralNegative
[62]   NumericLiteralUnsigned   ::=   INTEGER | DECIMAL | DOUBLE
[63]   NumericLiteralPositive   ::=   INTEGER_POSITIVE | DECIMAL_POSITIVE | DOUBLE_POSITIVE
[64]   NumericLiteralNegative   ::=   INTEGER_NEGATIVE | DECIMAL_NEGATIVE | DOUBLE_NEGATIVE
[65]   BooleanLiteral   ::=   'true' | 'false'
[66]   String   ::=   STRING_LITERAL1 | STRING_LITERAL2 | STRING_LITERAL_LONG1 | STRING_LITERAL_LONG2
[67]   IRIref   ::=   IRI_REF | PrefixedName
[68]   PrefixedName   ::=   PNAME_LN | PNAME_NS
[69]   BlankNode   ::=   BLANK_NODE_LABEL | ANON

Productions des terminaux :

[70]   IRI_REF   ::=   '<' ([^<>"{}|^`\]-[#x00-#x20])* '>'
[71]   PNAME_NS   ::=   PN_PREFIX? ':'
[72]   PNAME_LN   ::=   PNAME_NS PN_LOCAL
[73]   BLANK_NODE_LABEL   ::=   '_:' PN_LOCAL
[74]   VAR1   ::=   '?' VARNAME
[75]   VAR2   ::=   '$' VARNAME
[76]   LANGTAG   ::=   '@' [a-zA-Z]+ ('-' [a-zA-Z0-9]+)*
[77]   INTEGER   ::=   [0-9]+
[78]   DECIMAL   ::=   [0-9]+ '.' [0-9]* | '.' [0-9]+
[79]   DOUBLE   ::=   [0-9]+ '.' [0-9]* EXPONENT | '.' ([0-9])+ EXPONENT | ([0-9])+ EXPONENT
[80]   INTEGER_POSITIVE   ::=   '+' INTEGER
[81]   DECIMAL_POSITIVE   ::=   '+' DECIMAL
[82]   DOUBLE_POSITIVE   ::=   '+' DOUBLE
[83]   INTEGER_NEGATIVE   ::=   '-' INTEGER
[84]   DECIMAL_NEGATIVE   ::=   '-' DECIMAL
[85]   DOUBLE_NEGATIVE   ::=   '-' DOUBLE
[86]   EXPONENT   ::=   [eE] [+-]? [0-9]+
[87]   STRING_LITERAL1   ::=   "'" ( ([^#x27#x5C#xA#xD]) | ECHAR )* "'"
[88]   STRING_LITERAL2   ::=   '"' ( ([^#x22#x5C#xA#xD]) | ECHAR )* '"'
[89]   STRING_LITERAL_LONG1   ::=   "'''" ( ( "'" | "''" )? ( [^'\] | ECHAR ) )* "'''"
[90]   STRING_LITERAL_LONG2   ::=   '"""' ( ( '"' | '""' )? ( [^"\] | ECHAR ) )* '"""'
[91]   ECHAR   ::=   '\' [tbnrf\"']
[92]   NIL   ::=   '(' WS* ')'
[93]   WS   ::=   #x20 | #x9 | #xD | #xA
[94]   ANON   ::=   '[' WS* ']'
[95]   PN_CHARS_BASE   ::=   [A-Z] | [a-z] | [#x00C0-#x00D6] | [#x00D8-#x00F6] | [#x00F8-#x02FF] | [#x0370-#x037D] | [#x037F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
[96]   PN_CHARS_U   ::=   PN_CHARS_BASE | '_'
[97]   VARNAME   ::=   ( PN_CHARS_U | [0-9] ) ( PN_CHARS_U | [0-9] | #x00B7 | [#x0300-#x036F] | [#x203F-#x2040] )*
[98]   PN_CHARS   ::=   PN_CHARS_U | '-' | [0-9] | #x00B7 | [#x0300-#x036F] | [#x203F-#x2040]
[99]   PN_PREFIX   ::=   PN_CHARS_BASE ((PN_CHARS|'.')* PN_CHARS)?
[100]   PN_LOCAL   ::=   ( PN_CHARS_U | [0-9] ) ((PN_CHARS|'.')* PN_CHARS)?
Notez que les noms locaux SPARQL admettent des chiffres en tête, contrairement aux noms locaux XML.

Remarques :

  1. La grammaire SPARQL est LL(1) lorsque les règles avec des noms en majuscules sont utilisées comme terminaux ;
  2. Dans les nombres à signe, aucun caractère blanc n'est permis entre le signe et le nombre. La règle de grammaire AdditiveExpression l'autorise en couvrant les deux cas d'une expression suivie d'un nombre à signe. Cela produit une addition ou une substraction du nombre sans signe selon le cas.

Les fichiers de grammaire de quelques outils courants sont disponibles ici.

B. Conformité

Cf. l'annexe A Grammaire SPARQL à propos de la conformité des chaînes d'interrogation SPARQL, et la section 10 Formes d'interrogation pour la conformité des résultats d'interrogation. Cf. l'annexe E. Type de média Internet pour la conformité au type de média application/sparql-query.

Cette spécification est prévue pour être utilisée en conjonction avec le protocole SPARQL [SPROT] et le format XML des résultats d'interrogation SPARQL [RESULTS]. Cf. les critères de conformité de ces spécifications.

Notez que le protocole SPARQL décrit une interface abstraite ainsi qu'un protocole de réseau, et que l'interface abstraite peut aussi bien s'appliquer à des interfaces de programmation (API) qu'à des interfaces de réseau.

C. Observations à propos de la sécurité (informatif)

Les interrogations SPARQL utilisant des clauses FROM, FROM NAMED ou GRAPH peuvent provoquer la résolution de l'adresse URI indiquée. Cela peut entraîner une utilisation supplémentaire des ressources de réseau, de stockage ou de traitement (CPU) en même temps que des problèmes secondaires associés tels qu'une attaque par saturation (denial of service). Les problèmes de sécurité décrits à la section 7 de Identificateur de ressource uniforme (URI) — Syntaxe générique [RFC3986] devraient être pris en compte. En outre, le contenu des adresses URI de type file: peut dans certains cas être accédé, traité et retourné comme résultats, offrant un accès inattendu aux ressources locales.

Le langage SPARQL autorise les extensions, lesquelles auront leurs propres implications pour la sécurité.

Plusieurs adresses IRI peuvent avoir le même aspect. Des caractères d'écritures différentes peuvent sembler les mêmes (un caractère cyrillique "о" peut apparaître semblable à un caractère latin "o"). Un caractère suivi par des caractères combinatoires (combining characters) peut avoir la même représentation visuelle qu'un autre (un caractère LETTRE MINUSCULE LATINE E suivi d'un caractère LETTRE MODIFICATIVE ACCENT AIGU ont la même représentation visuelle qu'un caractère LETTRE MINUSCULE LATINE E ACCENT AIGU). Les utilisateurs de SPARQL doivent faire attention de construire des interrogations avec des adresses IRI qui correspondent aux adresses IRI dans les données. On peut trouver plus de renseignements à propos de la comparaison de caractères similaires dans Unicode Security Considerations [UNISEC] et Identificateurs de ressource internationalisés (IRI) [RFC3987], section 8.

D. Type de média Internet, extension de fichier et type de fichier Macintosh

Contact :
Eric Prud'hommeaux
Cf. également :
Comment enregistrer un type de média pour une spécification du W3C
Enregistrement d'un type de média Internet, uniformité d'utilisation
Conclusion du TAG du 3 juin 2002 (révisée le 4 septembre 2002)

Le type de média Internet, ou type MIME, du langage d'interrogation SPARQL est "application/sparql-query".

Il est recommandé que les fichiers d'interrogation SPARQL aient l'extension ".rq" (tout en minuscules) sur toutes les plateformes.

Il est recommandé que les fichiers d'interrogation SPARQL stockés sur le système de fichiers HFS Macintosh reçoivent le type de fichier "TEXT".

Nom de type :
application
Nom de sous-type :
sparql-query
Paramètres obligatoires :
Néant
Paramètres optionnels :
Néant
Observations à propos du codage :
La syntaxe du langage d'interrogation SPARQL s'exprime sur des points de code Unicode [UNICODE]. Le codage est toujours UTF-8 [RFC3629].
Les points de code Unicode peuvent aussi être exprimés en utilisant une syntaxe de la forme \uXXXX (U+0 à U+FFFF) ou \UXXXXXXXX (à partir de U+10000 et au-delà), où X est un chiffre hexadécimal [0-9A-F]
Observations à propos de la sécurité :
Cf. l'annexe C Observations à propos de la sécurité de la spécification du langage d'interrogation SPARQL ainsi que la section 7 Observations à propos de la sécurité du RFC 3629 [RFC3629].
Observations à propos de l'interopérabilité :
On ne connaît pas de problème d'interopérabilité.
Spécification publiée :
Cette spécification.
Applications utilisant ce type de média :
On ne connaît pas d'applications utilisant actuellement ce type de média.
Informations supplémentaires :
Numéro(s) magique(s) :
Une interrogation SPARQL peut avoir la chaîne 'PREFIX' (insensible à la casse) près du début du document.
Extension(s) de fichier :
".rq"
Adresse URI de base :
Le terme 'BASE <IRIref>' de SPARQL peut changer l'adresse URI de base courante des références IRI relatives dans le langage d'interrogation, utilisées ensuite en succession dans le document.
Code(s) de type de fichier Macintosh :
"TEXT"
Personne & courrier électronique à contacter pour d'autres renseignements :
public-rdf-dawg-comments@w3.org
Utilisation prévue :
COMMON
Restrictions d'utilisation :
Néant
Auteur ou contrôleur des changements :
La spécification SPARQL est un produit fonctionnel du groupe de travail RDF Data Access du World Wide Web Consortium. Le W3C contrôle les changements sur ces spécifications.

E. Références

Références normatives

[CHARMOD]
Modèle de caractères pour le Web 1.0 — Principes de base, R. Ishida, F. Yergeau, M. J. Düst, M. Wolf, T. Texin, rédacteurs, recommandation du W3C, 15 février 2005, http://www.w3.org/TR/2005/REC-charmod-20050215/.Dernière version disponible à http://www.w3.org/TR/charmod/.
[CONCEPTS]
Cadre de description de ressources (RDF) — Concepts et syntaxe abstraite, G. Klyne, J. J. Carroll, rédacteurs, recommandation du W3C, 10 février 2004, http://www.w3.org/TR/2004/REC-rdf-concepts-20040210/. Dernière version disponible à http://www.w3.org/TR/rdf-concepts/.
[FUNCOP]
Fonctions et opérateurs XQuery 1.0 et XPath 2.0, J. Melton, A. Malhotra, N. Walsh, rédacteurs, recommandation du W3C, 23 janvier 2007, http://www.w3.org/TR/2007/REC-xpath-functions-20070123/. Dernière version disponible à http://www.w3.org/TR/xpath-functions/.
[RDF-MT]
Sémantique RDF, P. Hayes, rédacteur, recommandation du W3C, 10 février 2004, http://www.w3.org/TR/2004/REC-rdf-mt-20040210/. Dernière version disponible à http://www.w3.org/TR/rdf-mt/.
[RFC3629]
RFC 3629 UTF-8 — Un format de transformation de ISO 10646, F. Yergeau, novembre 2003
[RFC4647]
RFC 4647 Correspondance des étiquettes de langue, A. Phillips, M. Davis, septembre 2006
[RFC3986]
RFC 3986 Identificateur de ressource uniforme (URI) — Syntaxe générique, T. Berners-Lee, R. Fielding, L. Masinter, janvier 2005
[RFC3987]
RFC 3987 Identificateurs de ressource internationalisés (IRI), M. Dürst , M. Suignard.
[UNICODE]
The Unicode Standard, Version 4. ISBN 0-321-18578-1, tel que mis à jour par la publication de nouvelles versions. La dernière version d'Unicode et des précisions sur les versions du standard et la base de données des caractères Unicode sont disponibles à http://www.unicode.org/unicode/standard/versions/.
[XML11]
Langage de balisage extensible (XML) 1.1, J. Cowan, J. Paoli, E. Maler, C. M. Sperberg-McQueen, F. Yergeau, T. Bray, rédacteurs, recommandation du W3C, 4 février 2004, http://www.w3.org/TR/2004/REC-xml11-20040204/. Dernière versions disponible à http://www.w3.org/TR/xml11/.
[XPATH20]
Langage de chemin XML (XPath) 2.0, A. Berglund, S. Boag, D. Chamberlin, M. F. Fernández, M. Kay, J. Robie, J. Siméon, rédacteurs, recommandation du W3C, 23 janvier 2007, http://www.w3.org/TR/2007/REC-xpath20-20070123/. Dernière version disponible à http://www.w3.org/TR/xpath20/.
[XQUERY]
XQuery 1.0 — Un langage d'interrogation XML, S. Boag, D. Chamberlin, M. F. Fernández, D. Florescu, J. Robie, J. Siméon, rédacteurs, recommandation du W3C, 23 janvier 2007, http://www.w3.org/TR/2007/REC-xquery-20070123/. Dernière version disponible à http://www.w3.org/TR/xquery/.
[XSDT]
XML Schema tome 2 — Types de données (deuxième édition), P. V. Biron, A. Malhotra, rédacteurs, recommandation du W3C, 28 octobre 2004, http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/. Dernière version disponible à http://www.w3.org/TR/xmlschema-2/ .
[BCP47]
Pratiques exemplaires 47, P. V. Biron, A. Malhotra, rédacteurs, recommandation du W3C, 28 October 2004, http://www.rfc-editor.org/rfc/bcp/bcp47.txt.

Références informatives

[CBD]
CBD - Concise Bounded Description, Patrick Stickler, Nokia, soumission d'un membre du W3C, 3 juin 2005.
[DC]
Expression des métadonnées Simple Dublin Core en RDF/XML, Dublin Core Dublin Core Metadata Initiative, recommandation du 31 juillet 2002.
[Multiset]
Multiset, Wikipedia, The Free Encyclopedia. Article tel que paru le 25 octobre 2007 à http://en.wikipedia.org/w/index.php?title=Multiset&oldid=163605900. La dernière version de cet article est à http://en.wikipedia.org/wiki/Multiset.
[OWL-Semantics]
Sémantique et syntaxe abstraite du langage d'ontologie web OWL, Peter F. Patel-Schneider, Patrick Hayes, Ian Horrocks, rédacteurs, recommandation du W3C http://www.w3.org/TR/2004/REC-owl-semantics-20040210/. Dernière version à http://www.w3.org/TR/owl-semantics/.
[RDFS]
Langage de description de vocabulaire RDF 1.0 — RDF Schema, Dan Brickley, R.V. Guha, rédacteurs, recommandation du W3C, 10 février 2004, http://www.w3.org/TR/2004/REC-rdf-schema-20040210/ . Dernière version à http://www.w3.org/TR/rdf-schema/.
[RESULTS]
Format XML des résultats d'interrogation SPARQL, D. Beckett, rédacteur, recommandation du W3C, 15 janvier 2008, http://www.w3.org/TR/2008/REC-rdf-sparql-XMLres-20080115/. Dernière version disponible à http://www.w3.org/TR/rdf-sparql-XMLres/.
[SPROT]
Protocole SPARQL pour RDF, K. Clark, rédacteur, recommandation du W3C, 15 janvier 2008, http://www.w3.org/TR/2008/REC-rdf-sparql-protocol-20080115/. Dernière version disponible à http://www.w3.org/TR/rdf-sparql-protocol/.
[TURTLE]
Turtle - Terse RDF Triple Language, Dave Beckett.
[UCNR]
Cas d'utilisation et exigences de l'accès aux données RDF, K. Clark, rédacteur, version préliminaire du W3C, 25 mars 2005, http://www.w3.org/TR/2005/WD-rdf-dawg-uc-20050325/. Dernière version disponible à http://www.w3.org/TR/rdf-dawg-uc/.
[UNISEC]
Unicode Security Considerations, Mark Davis, Michel Suignard
[VCARD]
Représentation des objets vCard en RDF/XML, Renato Iannella, note du W3C, 22 février 2001, http://www.w3.org/TR/2001/NOTE-vcard-rdf-20010222/. Dernière version disponible à http://www.w3.org/TR/vcard-rdf.
[WEBARCH]
Architecture du Web tome 1, I. Jacobs, N. Walsh, rédacteurs, recommandation du W3C, 15 décembre 2004, http://www.w3.org/TR/2004/REC-webarch-20041215/. Dernière version disponible à http://www.w3.org/TR/webarch/.
[UNIID]
Identifier and Pattern Syntax 4.1.0, Mark Davis, Unicode Standard Annex #31, 25 mars 2005, http://www.unicode.org/reports/tr31/tr31-5.html. Dernière version disponible à http://www.unicode.org/reports/tr31/.
[SPARQL-sem-05]
A relational algebra for SPARQL, Richard Cyganiak, 2005
[SPARQL-sem-06]
Semantics of SPARQL, Jorge Pérez, Marcelo Arenas, and Claudio Gutierrez, 2006.

F. Remerciements (informatif)

Le langage d'interrogation RDF SPARQL est un produit de l'ensemble du groupe de travail RDF Data Access du W3C, et nos remerciements pour les débats, commentaires et revues vont à tous les membres présents et passés.

Nous avons en outre débattu et discuté avec de nombreuses personnes au travers de la liste aux commentaires du groupe de travail. Tous les commentaires ont participé à améliorer le document. Andy voudrait également remercier en particulier Jorge Peérez, Geoff Chappell, Bob MacGregor, Yosi Scharf et Richard Newman pour avoir exploré les problèmes spécifiques en rapport avec SPARQL. Eric voudrait signaler l'aide incalculable de Björn Höhrmann.

Journal des changements

Voici un récapitulatif au niveau supérieur des changements apportés à ce document depuis la publication de la recommandation candidate du 14 juin 2007 :