检索owl中特定子类的类名

时间:2013-12-29 21:04:30

标签: python-2.7 sparql owl rdflib

我是rdflib初学者,我有一个关于类和子类的本体,我需要在子类中查找特定的单词,如果找到它,则返回其类名。

我有以下代码:

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"

当我print qres的结果时,它返回一个完整的URL,而我只需要子类和类的名称。

任何人都可以帮忙解决这个问题。

2 个答案:

答案 0 :(得分:1)

您尚未显示您的数据,因此我无法使用您的确切查询或数据,但根据您的评论,听起来您正在获取IRI(例如,http://www.semanticweb.org/raya/ontologies/test6#Good-behaviour)作为结果,并且你只想要字符串Good-behaviour。您可以使用strafter来执行此操作。例如,如果你有这样的数据:

@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 .

然后像这样的查询将返回具有完整IRI的结果:

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> |
---------------------------------------------------------------------------------------------------------

您可以使用strafter在其他字符串之后获取字符串的一部分。如,

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" |
-------------------------------------------------------------

如果您在查询中定义了前缀,例如so:,那么您也可以使用str(so:)代替字符串形式。如果您愿意,还可以在变量列表中进行字符串操作,而不是图形模式。这看起来像这样:

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" |
-------------------------------------------------------------

答案 1 :(得分:1)

您可以在没有SPARQL和Python字符串操作的情况下使用RDFLib来获得答案。如果您更喜欢使用SPARQL,Joshua Taylor answer to this question将是您的选择。您也不需要使用最新版本(4+)RDFLib的SPARQL处理器插件 - 请参阅"Querying with SPARQL" documentation

要获得您正在寻找的答案,您可以使用RDFLIB Graph方法subject_objects来获取具有您感兴趣的谓词的主题和对象的生成器,rdfs:subClassOf。每个主题和对象都是RDFLib URIRef,它们也是可以使用standard Python methods操纵的Python unicode对象。要获取IRI的后缀,请调用对象的split方法,并获取返回列表中的最后一项。

以下是您所做的代码重新编写。没有这些数据,我无法对其进行全面测试,但在使用不同的本体时,这对我有用。

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'