I have an RDF graph G with several classes assuming for simplicity (Person and Parrot).
The class Person
is connected to the class Parrot
by the property hasAnimal
, e.g.:
@PREFIX : <http://example.org/>
:Hugo rdf:type :Person .
:Hugo rdfs:label "Hugo" .
:Hugo :hasAnimal :Birdy.
:Birdy rdf:type :Parrot .
:Birdy rdfs:label :"Birdy" .
:LonleyBrido rdf:type :Parrot .
What is wanted is a subgraph of G that contains all the triples from Person and Parrot that are directly connected with each other, starting from Person. The initial Person does not matter to me, the important part is that only connected triples are extracted i.e. that only persons that do have a parrot or don't get outputted. What I have already tried is the following:
construct {
?person ?p ?o .
?parrot ?p2 ?o2 .
} where {
?person rdf:type :Person .
?person ?p ?o .
?person :hasAnimal ?parrot .
?parrot rdf:type :Parrot .
?parrot ?p2 ?o2 .
}
So the expected output would be:
:Hugo rdf:type :Person .
:Hugo rdfs:label "Hugo" .
:Hugo :hasAnimal :Birdy.
:Birdy rdf:type :Parrot .
:Birdy rdfs:label :"Birdy" .
I am executing this query on a rdflib
graph.
Does anyone have a solution to this problem?
The solution is already described above:
import rdflib
from rdflib.namespace import RDF, RDFS
query = """
construct {
?person ?p ?o .
?parrot ?p2 ?o2 .
} where {
?person rdf:type :Person .
?person ?p ?o .
?person :hasAnimal ?parrot .
?parrot rdf:type :Parrot .
?parrot ?p2 ?o2 .
}
"""
g = rdflib.Graph()
g.parse("example.ttl", format="ttl")
g.bind("rdf", RDF)
g.bind("rdfs", RDFS)
EX= rdflib.Namespace("http://example.org/")
g.bind("example", EX)
result = g.query(query)