Domanda

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.

È stato utile?

Soluzione

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'

Altri suggerimenti

You haven't shown your data, so I can't use your exact query or data, but based on your comments, it sounds like you're getting IRIs (e.g., http://www.semanticweb.org/raya/ontologies/test6#Good-behaviour) as results, and you want just the string Good-behaviour. You can use strafter to do that. For instance, if you had data like this:

@prefix : <http://stackoverflow.com/questions/20830056/> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>

:retrieving-the-class-name-of-a-specific-subclass-in-owl 
  rdfs:label "retrieving the class name of a specific subclass in owl"@en .

Then a query like this will return results that have full IRIs:

prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>

select ?question where { 
  ?question rdfs:label ?label .
}
---------------------------------------------------------------------------------------------------------
| question                                                                                              |
=========================================================================================================
| <http://stackoverflow.com/questions/20830056/retrieving-the-class-name-of-a-specific-subclass-in-owl> |
---------------------------------------------------------------------------------------------------------

You can use strafter to get the part of a string after some other string. E.g.,

prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>

select ?q where { 
  ?question rdfs:label ?label .
  bind(strafter(str(?question),"http://stackoverflow.com/questions/20830056/") as ?q)
}
-------------------------------------------------------------
| q                                                         |
=============================================================
| "retrieving-the-class-name-of-a-specific-subclass-in-owl" |
-------------------------------------------------------------

If you define the prefix in the query, e.g., as a so:, then you can also use str(so:) instead of the string form. If you prefer, you can also do the string manipulation in the variable list rather than the graph pattern. That would look like this:

prefix so: <http://stackoverflow.com/questions/20830056/> 
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>

select (strafter(str(?question),str(so:)) as ?q) where { 
  ?question rdfs:label ?label .
}
-------------------------------------------------------------
| q                                                         |
=============================================================
| "retrieving-the-class-name-of-a-specific-subclass-in-owl" |
-------------------------------------------------------------
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top