Search code examples
python-2.7sparqlowlrdflib

retrieving the class name of a specific subclass in owl


I am an rdflib beginner, i have an ontology with classes and sub-classes and I need to look for a specific word in a subclass and, if it is found, return its class name.

I have the following code:

import rdflib
from rdflib import plugin
from rdflib.graph import Graph

g = Graph()
g.parse("test.owl")
from rdflib.namespace import Namespace
plugin.register(
  'sparql', rdflib.query.Processor,
  'rdfextras.sparql.processor', 'Processor')
plugin.register(
  'sparql', rdflib.query.Result,
  'rdfextras.sparql.query', 'SPARQLQueryResult')

qres = g.query("""
  PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
  PREFIX owl: <http://www.w3.org/2002/07/owl#>
  PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
  PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

   SELECT  ?subject ?object
WHERE { ?subject rdfs:subClassOf ?object } 

  """)
# n is asubclass name and its class name is good-behaviour which i want to be the result
n="pity"
for (subj,pred,obj) in qres:
  if n in subj:
    print obj
  else:
    print "not found"

When I print the result of qres it returns a complete URL, and I need the name only of the sub-class and the class.

Can anyone help with this.


Solution

  • You can use RDFLib without SPARQL and Python string manipulation to get your answer. If you prefer to use SPARQL, the Joshua Taylor answer to this question would be the way to go. You also don't need the SPARQL processor plugin with recent versions (4+) of RDFLib - see the "Querying with SPARQL" documentation.

    To get the answer you are looking for you can use the RDFLIB Graph method subject_objects to get a generator of subjects and objects with the predicate you are interested in, rdfs:subClassOf. Each subject and object will be an RDFLib URIRef, which are also Python unicode objects that can be manipulated using standard Python methods. To get the suffix of the IRI call the split method of the object and take the last item in the returned list.

    Here is your code reworked to do as described. Without the data, I can't fully test it but this did work for me when using a different ontology.

    from rdflib import Graph
    from rdflib.namespace import RDFS
    
    g = Graph()
    g.parse("test.owl")
    
    # n is a subclass name and its class name is good-behaviour
    # which i want to be the result
    n = "pity"
    
    for subj, obj in g.subject_objects(predicate=RDFS.subClassOf):
        if n in subj:
            print obj.rsplit('#')[-1]
        else:
            print 'not found'