Last April Richard Cyganiak tweeted the following:

@iand @ldodds "use this term if available, else fall back to that one" is common when consuming RDF, not well supported by SPARQL or RDFS

I took this as a challenge (if not as a very pressing one, if I waited this long to follow through). I managed to write a SPARQL query that reads the following data and sets ?label to the skos:prefLabel value if it's available and otherwise to the rdfs:label value:

@prefix skos: <http://www.w3.org/2004/02/skos/core#> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . @prefix : <http://rdfdata.org/whatever#> . :thing1 rdfs:label "Robert"; skos:prefLabel "Bob" . :thing2 rdfs:label "Jane". :thing3 skos:prefLabel "Frank".

Here's the output, using ARQ:

----------- | label | =========== | "Frank" | | "Bob" | | "Jane" | -----------

Here's a SPARQL 1.0 version of the query:

PREFIX skos: <http://www.w3.org/2004/02/skos/core#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> SELECT ?label # Bind ?label to WHERE { { # skos:prefLabel if available ?s skos:prefLabel ?label . } UNION # and rdfs:label if not. { ?s rdfs:label ?label . OPTIONAL { ?s skos:prefLabel ?prefLabel .} FILTER (!bound(?prefLabel)) . } }

It asks for the union of any skos:prefLabel values and any rdfs:label values but to filter out any of the latter that have a skos:prefLabel property for the same subject. The query is verbose, and the FILTER(!bound()) trick is non-intuitive enough to have inspired two nicer substitutes in SPARQL 1.1: MINUS and FILTER NOT EXISTS. Here's the query with MINUS:

PREFIX skos: <http://www.w3.org/2004/02/skos/core#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> SELECT ?label # Bind ?label to WHERE { { # skos:prefLabel if available ?s skos:prefLabel ?label . } UNION # and rdfs:label if not. { ?s rdfs:label ?label . MINUS { ?s skos:prefLabel ?prefLabel } } }

You could substitute FILTER NOT EXISTS for MINUS there, and it would work the same way with a SPARQL engine that implements 1.1 such as ARQ.

It's one less line than the SPARQL 1.0 version, and a bit easier to read, but it's still a verbose way to assign skos:prefLabel to ?label if it's available and otherwise rdfs:label . The important thing, though, is that it can be done with standard SPARQL, and that it's a little easier with 1.1.

Can you improve on this query at all?