Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sparql query for children, grandchildren, .. of a class

I have an owl file I built in Protege. What is the sparql query which will select all the subclasses of a class and all the subclasses of those subclasses, so on and so on (Breadth First Search Sort of Manner)?

like image 978
Nick Avatar asked Nov 01 '25 15:11

Nick


1 Answers

This might be answered by Sparql query Subclass or EquivalentTo, but that question and its answer contain a lot more information that what you're asking for here. You can't really enforce the search strategy (depth first vs. breadth first), but you can (sort of) order subclasses by their distance from the root, if there's a unique path from the root to the subclass. First, let's get some sample data:

@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
@prefix : <https://stackoverflow.com/q/23094361/1281433/>.

#            a
#          /   \
#         b     c
#        / \   / \
#       d   e f   g 

:b rdfs:subClassOf :a .
:c rdfs:subClassOf :a .

:d rdfs:subClassOf :b .
:e rdfs:subClassOf :b .

:f rdfs:subClassOf :c .
:g rdfs:subClassOf :c .

You can use a query like this to get the subclasses of :a:

prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix : <https://stackoverflow.com/q/23094361/1281433/>

select ?subclass where {
  ?subclass rdfs:subClassOf* :a
}
------------
| subclass |
============
| :a       |
| :c       |
| :g       |
| :f       |
| :b       |
| :e       |
| :d       |
------------

The results include :a because we used the path rdfs:subClassOf*. This is logically correct, since a class is a subclass of itself, but if you don't want :a included, you could use rdfs:subClassOf+, or you could filter out :a with filter( ?subclass != :a ).

In the case that there's a single path from the root to the subclass, you can count the intermediate nodes between them to determine their depth. If you order by depth in this way, then you'll get your results in something like what a breadth first search would give you the following. This technique is described in more detail in Is it possible to get the position of an element in an RDF Collection in SPARQL? and Calculate length of path between nodes?.

prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix : <https://stackoverflow.com/q/23094361/1281433/>

select ?subclass (count(?intermediate)-1 as ?depth) where {
  ?subclass rdfs:subClassOf* ?intermediate .
  ?intermediate rdfs:subClassOf* :a .
}
group by ?subclass
order by ?depth
--------------------
| subclass | depth |
====================
| :a       | 0     |
| :b       | 1     |
| :c       | 1     |
| :d       | 2     |
| :e       | 2     |
| :f       | 2     |
| :g       | 2     |
--------------------
like image 169
Joshua Taylor Avatar answered Nov 03 '25 12:11

Joshua Taylor



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!