我正在尝试使用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>               |
--------------------------------------------------------

08-07 19:07