Selecting paths of length one
The property path using *
finds paths of length zeor or greater. If you want paths of length exactly one, just remove the *
:
select ?object where {
:SUB rdfs:superClassOf ?object
}
I'd note though that RDFS only defines rdfs:subClassOf
, not rdfs:superClassOf
which you've used in your query. I'll assume that it's just a typo in the question, though. I think the actual query you'd want would be:
select ?subclass where {
?subclass rdfs:subClassOf :SUB
}
Selecting arbitrary length paths
The solutions in this section are based on an answer to a question about finding the position of elements in an RDF list. Consider this data:
@prefix : <urn:ex:> .
:a :p :b, :c .
:b :p :d, :e .
This query finds chains on p
along with the lengths of the chains:
prefix : <urn:ex:>
select ?sub ?sup (count(?mid)-1 as ?distance) where {
?sub :p* ?mid .
?mid :p* ?sup .
}
group by ?sub ?sup
order by ?sub ?sup
$ arq --data data.n3 --query query.sparql
------------------------
| sub | sup | distance |
========================
| :a | :a | 0 |
| :a | :b | 1 |
| :a | :c | 1 |
| :a | :d | 2 |
| :a | :e | 2 |
| :b | :b | 0 |
| :b | :d | 1 |
| :b | :e | 1 |
| :c | :c | 0 |
| :d | :d | 0 |
| :e | :e | 0 |
------------------------
Since we can get the length of the paths we can filter
on that length and get just the ones we want. For instance:
prefix : <urn:ex:>
select ?sub ?sup where {
{
select ?sub ?sup (count(?mid)-1 as ?distance) where {
?sub :p* ?mid .
?mid :p* ?sup .
}
group by ?sub ?sup
order by ?sub ?sup
}
filter( ?distance = 2 )
# filter ( ?distance > 2 ) # alternative
# filter ( ?distance < 10 ) # alternative
}
$ arq --data data.n3 --query query.sparql
-------------
| sub | sup |
=============
| :a | :d |
| :a | :e |
-------------
When you just want paths of small, but specific length, you can expand the property path manually. E.g., for paths of length two:
prefix : <urn:ex:>
select ?sub ?sup {
?sub :p/:p ?sup .
}
For a range of numbers, e.g., 1–2, you can use the ?
which matches zero or one:
prefix : <urn:ex:>
select ?sub ?sup {
?sub :p/:p? ?sup .
}
For more about property paths, be sure to take a look at section 9 Property Paths in the SPARQL 1.1 specification.