如何使用Jena OntModel.listClasses()方法?

Art*_*sse 2 java inference subclass jena

我正在尝试使用Jena OntModel来获得本体的直接关系.问题来自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>.
Run Code Online (Sandbox Code Playgroud)

我基本上希望能够获得所有类,并为每个类获取subClasses.

我使用以下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...

    }
Run Code Online (Sandbox Code Playgroud)

打印显示本体模型已正确加载并完成基本推理.它还表明,当请求类的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 )
Run Code Online (Sandbox Code Playgroud)

有谁知道为什么OntModel.getClasses()不返回任何东西?

Jos*_*lor 5

由于两个原因你没有得到任何结果.

  1. 默认的本体配置文件是一个OWL配置文件,因此您在没有特定的OntModelSpec的情况下使用getOntologyModel获得OWL模型.相反,您可能应该使用RDFS本体模型.这将使listClasses查找rdfs:Class而不是owl:Class的实例.但是,这仍然只能得到一个结果,因为你只宣称一件事是rdfs:Class.
  2. 你只声明了一个作为rdfs:Class的东西,其余的应该被推断为rdfs:基于它们是其他东西的子类这一事实的类.这意味着您需要使用推理模型.在这种情况下,您可能需要RDFS推理模型,但由于(某些)Jena的OWL reasoners包含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 ==");
    }
}
Run Code Online (Sandbox Code Playgroud)
== 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 ==
Run Code Online (Sandbox Code Playgroud)

这有一些你没有提到的类,因为RDFS公理需要它们.如果您只想要声明为rdfs:数据中的类及其子类的内容,则可以使用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 );
Run Code Online (Sandbox Code Playgroud)
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>

select distinct ?class where {
  { ?class a rdfs:Class } union
  { ?class rdfs:subClassOf|^rdfs:subClassOf [] }
}
Run Code Online (Sandbox Code Playgroud)
--------------------------------------------------------
| 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>               |
--------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)