sparql-endpoint provides utilities for interfacing with SPARQL 1.1 endpoints in clojure.
sparql-endpoint is available as a Maven artifact from clojars.
Require thus:
(ns my.namespace
(:require
[ont-app.sparql-endpoint.core :as endpoint]
))
These involve POSTs to an update endpoint and GETs to a query
enpoint. There are special functions for ASK, SELECT and CONSTRUCT
queries. Each of these take mandatory endpoint and query
arguments, and an optional http-req argument.
endpoint and queryAll of the basic query and update functions take two mandatory arguments:
endpoint is the URL of a SPARQL endpoint
query is a string in an appropriate format for ASK, SELECT,
CONSTRUCT, or one of the UPDATE operations.
http-reqHTTP calls are done through clj-http. There is a third optional
http-req argument which may include additional HTTP request
parameters.
For example if endpointrequires authentication, you may specify
{:basic-auth "myUserName:myPassword"}
{:cookie-policy :standard} is asserted by default, but this can
be overridden. The :query-params parameter is reserved, as it is
needed to specify the query to the endpoint.
This function takes an endpoint and a SPARQL ASK query and returns a boolean:
(use 'ont-app.sparql-endpoint.core)
(sparql-ask
"https://query.wikidata.org/bigdata/namespace/wdq/sparql"
"ASK WHERE {wd:Q5 rdfs:label \"human\"@en}")
;; --> true
This function takes as its query parameter a SPARQL SELECT query:
(use 'ont-app.sparql-endpoint.core)
(let [query "
# What is the English name for Q5?
PREFIX rdfs: `
PREFIX wd: <http://www.wikidata.org/entity/>
SELECT ?enLabel
WHERE
{
wd:Q5 rdfs:label ?enLabel.
Filter (Lang(?enLabel) = \"en\")
}"
]
(sparql-select
"https://query.wikidata.org/bigdata/namespace/wdq/sparql"
query)
;; => [{"enLabel" {"xml:lang" "en", "type" "literal", "value" "human"}}]
The bindings returned are direct translations of the JSON returned by
the endpoint. These can be mapped by more expressive simplifiers,
described below.
This function takes a SPARQL CONSTRUCT query as its query parameter and returns a string of turtle describing the results.
(use 'ont-app.sparql-endpoint.core)
(let [query "
# Things called 'human'
PREFIX eg: <http://example.com/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX wd: <http://www.wikidata.org/entity/>
CONSTRUCT
{
?human a eg:Human.
}
WHERE
{
?human rdfs:label \"human\"@en.
}"
]
(sparql-construct
"https://query.wikidata.org/bigdata/namespace/wdq/sparql"
query))
;; -> "
@prefix eg: <http://example.com/> .
@prefix wd: <http://www.wikidata.org/entity/> .
wd:Q823310 a eg:Human .
wd:Q20094897 a eg:Human .
wd:Q26190966 a eg:Human .
wd:Q5 a eg:Human .
"
This function POSTS its query parameter (CREATE, INSERT, DELETE, etc) to the specified SPARQL update endpoint, and returns the plain text response.
By default the output of sparql-select is parsed JSON of raw
output of the endpoint, using the specification described by W3C.
{'value' <value>
'type' 'uri' | 'literal'
;;...maybe...
'xml:lang' <lang> (if literal)
'datatype' <datatype> (if literal)
}
It is usually convenient to transform these bindings into simpler
representations. Hence the functions simplify and
simplifier-for-prologue, described below.
The function simplify will take a result binding and return a simplified map {<var> <value>...}. This would typically be done in the context of a map function:
(use 'ont-app.sparql-endpoint.core)
(let [query "
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX wd: <http://www.wikidata.org/entity/>
SELECT ?enLabel
WHERE
{
wd:Q5 rdfs:label ?enLabel.
Filter (Lang(?enLabel) = \"en\")
}"
]
(map simplify (sparql-select wikidata-endpoint query))
;; => ({:enLabel "human"})
;; Compare to [{"enLabel" {"xml:lang" "en", "type" "literal", "value" "human"}}]
translators argumentsimplify takes an optional argument translators, a map with three
keys: :uri, :lang and :datatype. Default values for this map are
defined as the value default-translators.
| key | description | default |
|---|---|---|
:uri | value is a uri | return raw value (typically "http://...") |
:lang | value is literal and has a language tag, e.g. "en" | return raw value (without the language tag) |
:datatype | value is literal and has an assigned datatype, g.g. "xsd:int" | parse XSD values, otherwise return raw value |
:bnode | value is a blank node | return raw value, typically like "b0" |
By default the Jena library is referenced to translate xsd datatypes into instances of an appropriate class. In the following example, Obama's date of birth is translated to an instance of Jena's XSDDateTime, which has a getYears method:
(use 'ont-app.sparql-endpoint.core)
(let [query "
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX wd: <http://www.wikidata.org/entity/>
# What is Obama's date of birth?
SELECT ?dob
WHERE
{
wd:Q76 wdt:P569 ?dob.
} "
]
(.getYears (:dob (nth (map simplify
(sparql-select wikidata-endpoint query))
0))))
;; -> 1961
Any of these values can be overridden with custom functions by merging default-translators with an overriding map.
This function takes a query with a prologue (Including a set of PREFIX declarations) and returns a simplifier function informed by a function which maps full URIs to their corresponding quicknames. It is informed by the function parse-prologue, described below.
Compare this…
(use 'ont-app.sparql-endpoint.core)
(let [query "
# Things called 'Barack Obama'
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX wd: <http://www.wikidata.org/entity/>
SELECT *
WHERE
{
?Q rdfs:label \"Barack Obama\"@en.
}"
]
(map simplify
(sparql-select wikidata-endpoint query)))
;; -> ({:Q "http://www.wikidata.org/entity/Q76"}
;; {:Q "http://www.wikidata.org/entity/Q47513588"})
… to this …
(use 'ont-app.sparql-endpoint.core)
(let [query "
# Things called 'Barack Obama'
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX wd: <http://www.wikidata.org/entity/>
SELECT *
WHERE
{
?Q rdfs:label \"Barack Obama\"@en.
}"
]
(map (simplifier-for-prologue query)
(sparql-select wikidata-endpoint query)))
;; => ({:Q "wd:Q76"} {:Q "wd:Q47513588"})
This function takes a SPARQL query and returns a vector with three values:
base, uri-to-quickname, quickname-to-uri.
| name | description |
|---|---|
| base | The base URI used to resolve relative URIs |
| uri-to-quickname | fn[uri] -> corresponding quickname |
| quickname-to-uri | fn[quickname] -> corresponding full URI |
Given a string for which there is no prefix declaration in the query, these last two functions will return their argument unchanged.
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |