我正在尝试使用Jena OntModel来获取本体的the direct relations。
问题来自listClasses()方法。
我在网上搜寻了一段时间的提示,但没有找到解决我问题的相关答案。
因此,这里有一个完整的示例,该示例以最少的数据和代码显示了问题所在。
例如,我有一个基本的本体(N-Triple格式):
<http://weblab.ow2.org/wookie#Anti-social_behaviour> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://weblab.ow2.org/wookie#CriminalEvent>.
<http://weblab.ow2.org/wookie#Robbery> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://weblab.ow2.org/wookie#CriminalEvent>.
<http://weblab.ow2.org/wookie#Vehicle_crime> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://weblab.ow2.org/wookie#CriminalEvent>.
<http://weblab.ow2.org/wookie#Bicycle_theft> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://weblab.ow2.org/wookie#CriminalEvent>.
<http://weblab.ow2.org/wookie#CriminalEvent> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://weblab.ow2.org/wookie#Event>.
<http://weblab.ow2.org/wookie#Event> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://weblab.ow2.org/wookie#WookieThing>.
<http://weblab.ow2.org/wookie#Event> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2000/01/rdf-schema#Class>.
我基本上希望能够获取所有类,并为每个类获取子类。
我使用以下JAVA代码:
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.util.FileManager;
public class Main {
public static void main(final String [] argv) throws FileNotFoundException, IOException {
final OntModel model = ModelFactory.createOntologyModel();
model.read(FileManager.get().open("./src/test/resources/eventOnto.n3"), "", "N-TRIPLE");
// This part allows to check that the ontology model is really loaded and that inference is
// correctly done. WORKING
final List<Statement> statements = model.listStatements().toList();
Collections.sort(statements, new Comparator<Statement>() {
@Override
public int compare(final Statement o1, final Statement o2) {
return o1.toString().compareTo(o2.toString());
}
});
for (final Statement statement : statements) {
System.out.println(statement);
}
System.out.println("-------------------------------------------------");
// Listing all the classes.
final List<OntClass> classes = model.listClasses().toList();
for (final OntClass ontclass : classes) {
System.out.println(ontclass);
}
System.out.println("-------------------------------------------------");
// Bug got nothing. So try with a SPARQL query...
final Query query = QueryFactory.create("PREFIX rdf:<http://www.w3.org/2000/01/rdf-schema#> SELECT distinct ?class WHERE {?class a rdf:Class.}");
final ResultSet queryResult = QueryExecutionFactory.create(query, model).execSelect();
while (queryResult.hasNext()) {
System.out.println(queryResult.next());
}
// and got many results...
}
印刷品表明正确加载了本体模型并完成了基本推断。它还表明,在要求类的SPARQL查询获得每个单独的类时,getClasses()不会返回任何内容。
[http://weblab.ow2.org/wookie#Anti-social_behaviour, http://www.w3.org/1999/02/22-rdf-syntax-ns#type, http://www.w3.org/2000/01/rdf-schema#Class]
[http://weblab.ow2.org/wookie#Anti-social_behaviour, http://www.w3.org/1999/02/22-rdf-syntax-ns#type, http://www.w3.org/2000/01/rdf-schema#Resource]
[http://weblab.ow2.org/wookie#Anti-social_behaviour, http://www.w3.org/2000/01/rdf-schema#subClassOf, http://weblab.ow2.org/wookie#Anti-social_behaviour]
[http://weblab.ow2.org/wookie#Anti-social_behaviour, http://www.w3.org/2000/01/rdf-schema#subClassOf, http://weblab.ow2.org/wookie#CriminalEvent]
[http://weblab.ow2.org/wookie#Anti-social_behaviour, http://www.w3.org/2000/01/rdf-schema#subClassOf, http://weblab.ow2.org/wookie#Event]
[http://weblab.ow2.org/wookie#Anti-social_behaviour, http://www.w3.org/2000/01/rdf-schema#subClassOf, http://weblab.ow2.org/wookie#WookieThing]
[http://weblab.ow2.org/wookie#Anti-social_behaviour, http://www.w3.org/2000/01/rdf-schema#subClassOf, http://www.w3.org/2000/01/rdf-schema#Resource]
[http://weblab.ow2.org/wookie#Anti-social_behaviour, http://www.w3.org/2000/01/rdf-schema#subClassOf, http://www.w3.org/2002/07/owl#Thing]
...(many other lines)...
-------------------------------------------------
-------------------------------------------------
( ?class = rdf:Property )
( ?class = rdf:List )
( ?class = rdfs:Resource )
( ?class = rdfs:Class )
( ?class = rdf:Statement )
( ?class = rdfs:Literal )
( ?class = <http://weblab.ow2.org/wookie#Event> )
( ?class = rdf:XMLLiteral )
( ?class = owl:Thing )
( ?class = <http://weblab.ow2.org/wookie#WookieThing> )
( ?class = <http://weblab.ow2.org/wookie#CriminalEvent> )
( ?class = rdfs:Container )
( ?class = <http://weblab.ow2.org/wookie#Robbery> )
( ?class = <http://weblab.ow2.org/wookie#Bicycle_theft> )
( ?class = rdf:Seq )
( ?class = rdf:Alt )
( ?class = <http://weblab.ow2.org/wookie#Anti-social_behaviour> )
( ?class = <http://weblab.ow2.org/wookie#Vehicle_crime> )
( ?class = rdfs:ContainerMembershipProperty )
( ?class = rdf:Bag )
( ?class = rdfs:Datatype )
有谁知道为什么OntModel.getClasses()不返回任何东西?
最佳答案
您没有得到结果的原因有两个。
默认的本体配置文件是OWL配置文件,因此您可以使用不带特定OntModelSpec的getOntologyModel来获取OWL模型。相反,您可能应该使用RDFS本体模型。这将使listClasses查找rdfs:Class的实例,而不是owl:Class的实例。但是,那仍然只会给您一个结果,因为您仅声明了一件事情是rdfs:Class。
您仅将一件事声明为rdfs:Class,而其余部分则应根据它们是其他东西的子类推断为rdfs:Class。这意味着您需要使用推理模型。在这种情况下,您可能需要RDFS推理模型,但是由于(某些)耶拿的OWL推理程序包括RDFS规则,因此您也可以使用OWL模型。
以下代码将数据加载到几种不同类型的模型中,并显示listClasses的结果:
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.jena.riot.Lang;
import org.apache.jena.riot.RDFDataMgr;
import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
public class ListClassesExample {
public static void main(String[] args) throws IOException {
String content =
"<http://weblab.ow2.org/wookie#Anti-social_behaviour> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://weblab.ow2.org/wookie#CriminalEvent>.\n" +
"<http://weblab.ow2.org/wookie#Robbery> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://weblab.ow2.org/wookie#CriminalEvent>.\n" +
"<http://weblab.ow2.org/wookie#Vehicle_crime> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://weblab.ow2.org/wookie#CriminalEvent>.\n" +
"<http://weblab.ow2.org/wookie#Bicycle_theft> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://weblab.ow2.org/wookie#CriminalEvent>.\n" +
"<http://weblab.ow2.org/wookie#CriminalEvent> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://weblab.ow2.org/wookie#Event>.\n" +
"<http://weblab.ow2.org/wookie#Event> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://weblab.ow2.org/wookie#WookieThing>.\n" +
"<http://weblab.ow2.org/wookie#Event> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2000/01/rdf-schema#Class>.";
final Model base = ModelFactory.createDefaultModel();
try ( InputStream in = new ByteArrayInputStream( content.getBytes() )) {
RDFDataMgr.read( base, in, Lang.NTRIPLES );
}
System.out.println( "== OWL Classes (no inference) ==" );
OntModel owlOntology = ModelFactory.createOntologyModel( OntModelSpec.OWL_MEM, base );
for ( OntClass klass : owlOntology.listClasses().toList() ) {
System.out.println( klass );
}
System.out.println( "== RDFS Classes (no inference) ==" );
OntModel rdfsOntology = ModelFactory.createOntologyModel( OntModelSpec.RDFS_MEM, base );
for ( OntClass klass : rdfsOntology.listClasses().toList() ) {
System.out.println( klass );
}
System.out.println( "== RDFS Classes (with inference) ==" );
OntModel rdfsOntologyInf = ModelFactory.createOntologyModel( OntModelSpec.RDFS_MEM_RDFS_INF, base );
for ( OntClass klass : rdfsOntologyInf.listClasses().toList() ) {
System.out.println( klass );
}
System.out.println( "== End ==");
}
}
== OWL Classes (no inference) ==
== RDFS Classes (no inference) ==
http://weblab.ow2.org/wookie#Event
== RDFS Classes (with inference) ==
http://www.w3.org/1999/02/22-rdf-syntax-ns#Property
http://www.w3.org/1999/02/22-rdf-syntax-ns#List
http://www.w3.org/2000/01/rdf-schema#Resource
http://www.w3.org/2000/01/rdf-schema#Class
http://www.w3.org/1999/02/22-rdf-syntax-ns#Statement
http://www.w3.org/2000/01/rdf-schema#Literal
http://weblab.ow2.org/wookie#Event
http://weblab.ow2.org/wookie#WookieThing
http://weblab.ow2.org/wookie#CriminalEvent
http://www.w3.org/2000/01/rdf-schema#Container
http://weblab.ow2.org/wookie#Robbery
http://weblab.ow2.org/wookie#Bicycle_theft
http://www.w3.org/1999/02/22-rdf-syntax-ns#Seq
http://www.w3.org/1999/02/22-rdf-syntax-ns#Alt
http://weblab.ow2.org/wookie#Anti-social_behaviour
http://weblab.ow2.org/wookie#Vehicle_crime
http://www.w3.org/2000/01/rdf-schema#ContainerMembershipProperty
http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag
http://www.w3.org/2000/01/rdf-schema#Datatype
http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral
== End ==
其中有一些您没有提到的类,因为RDFS公理需要它们。如果只需要在数据中声明为rdfs:Class的东西及其子类,则可以使用SPARQL查询:
String query = "\n" +
"prefix rdfs: <"+RDFS.getURI()+">\n" +
"\n" +
"select distinct ?class where {\n" +
" { ?class a rdfs:Class } union\n" +
" { ?class rdfs:subClassOf|^rdfs:subClassOf [] }\n" +
"}";
ResultSet results = QueryExecutionFactory.create( query, base ).execSelect();
System.out.println( query );
ResultSetFormatter.out( results );
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select distinct ?class where {
{ ?class a rdfs:Class } union
{ ?class rdfs:subClassOf|^rdfs:subClassOf [] }
}
--------------------------------------------------------
| class |
========================================================
| <http://weblab.ow2.org/wookie#Event> |
| <http://weblab.ow2.org/wookie#Bicycle_theft> |
| <http://weblab.ow2.org/wookie#Anti-social_behaviour> |
| <http://weblab.ow2.org/wookie#WookieThing> |
| <http://weblab.ow2.org/wookie#Vehicle_crime> |
| <http://weblab.ow2.org/wookie#CriminalEvent> |
| <http://weblab.ow2.org/wookie#Robbery> |
--------------------------------------------------------