【问题标题】:How to add RDF triples to an OWLOntology?如何将 RDF 三元组添加到 OWLOntology?
【发布时间】:2013-07-02 09:10:26
【问题描述】:

我有一些来自 RabbitMQ 的数据。数据被格式化为三元组,因此来自队列的消息可能如下所示:

:Tom foaf:knows :Anna

其中: 是我想要导入数据的本体的标准命名空间,但导入的其他前缀也是可能的。三元组由主语、属性/谓词和宾语组成,我在每条消息中都知道哪个是哪个。

在接收端,我有一个带有 OWLOntology 对象的 Java 程序,该对象表示应该临时存储新到达的三元组用于推理和其他内容的本体。 我有点设法将三元组放入耶拿OntModel,但这就是它的终点。我尝试使用OWLRDFConsumer,但找不到任何有关如何应用它的信息。

我的函数看起来像这样:

public void addTriple(RDFTriple triple) {

    //OntModel model = ModelFactory.createOntologyModel();

    String subject = triple.getSubject().toString();
    subject = subject.substring(1,subject.length()-1);
    Resource s = ResourceFactory.createResource(subject);

    String predicate = triple.getPredicate().toString();
    predicate = predicate.substring(1,predicate.length()-1);
    Property p = ResourceFactory.createProperty(predicate);

    String object = triple.getObject().toString();
    object = object.substring(1,object.length()-1);
    RDFNode o = ResourceFactory.createResource(object);

    Statement statement = ResourceFactory.createStatement(s, p, o);
    //model.add(statement);

    System.out.println(statement.toString());
}

我做了子字符串操作,因为 RDFTriple 类在三元组的参数周围添加了 ,因此 Statement 的构造函数失败了。

如果有人能指出一个很好的例子。也许有一个更好的方法,我没有想过要实现同样的目标?

【问题讨论】:

  • 问题标题是“如何将 RDF 三元组添加到 OWLOntology?”您在问题中说您“设法将三元组放入 Jena OntModel。”你还需要做什么?你能告诉我们你到目前为止做了什么吗?
  • 啊,OWLOntology 和 OWLRDFConsumer 是 OWL API 类,所以看起来您正在尝试使用 OWL API 做一些事情。你能提供更多关于你到目前为止所做的事情的细节吗?您为将三元组导入 Jena OntModel 所做的工作也可能令人感兴趣。
  • 是的,抱歉,我没有提到它们是 OWLAPI 类。我一直在努力让它工作,现在将它添加到模型中的行为也失败了,我已经改变了很多东西,我不记得它的工作方式:(我将添加我的代码原来的问题。
  • RDFTripleRDFResources 作为主语和谓语,RDFNode 作为宾语。如果你getSubject 得到RDFResource,然后getResource 得到IRI,然后在上面使用toString,我想你会得到IRI 文本(而不是返回的toQuotedString用尖括号括起来的文本。
  • 我不必使用 RDFTriple。我得到的输入是纯 JSON,我只是认为我应该使用 RDFTriple 类,因为它就是这样 - 三元组。还是不行?

标签: java rdf ontology owl owl-api


【解决方案1】:

在 ONT-API 中,它是一个扩展的基于 Jena 的 OWL-API 实现,它非常简单:

    OWLOntologyManager manager = OntManagers.createONT();
    OWLOntology ontology = manager.createOntology(IRI.create("http://example.com#test"));
    ((Ontology)ontology).asGraphModel().createResource("http://example.com#clazz1").addProperty(RDF.type, OWL.Class);
    ontology.axioms(AxiomType.DECLARATION).forEach(System.out::println);

欲了解更多信息,请参阅ONT-API wiki, examples

【讨论】:

    【解决方案2】:

    OWLRDFConsumer 似乎通常用于将 RDF 解析器与支持 OWL 的处理器连接起来。但是,正如我在 cmets 中所指出的那样,以下代码似乎有效,有几个地方我需要一个参数并放入我能做的唯一可用的东西。

    以下代码:创建一个本体;宣布两个有名字的人,汤姆和安娜;声明一个对象属性,喜欢;并声明一个数据属性age。一旦声明了这些,我们打印本体只是为了确保它是我们所期望的。然后它创建一个 OWLRDFConsumer。消费者构造函数需要一个本体、一个AnonymousNodeChecker 和一个OWLOntologyLoaderConfiguration。对于配置,我只是使用了一个由无参数构造函数创建的,我认为没关系。对于节点检查器,唯一方便的实现者是 TurtleParser,所以我创建了其中一个,将 null 作为 Reader 传递。我认为这没问题,因为不会调用解析器来读取任何内容。然后使用消费者的handle(IRI,IRI,IRI)handle(IRI,IRI,OWLLiteral) 方法一次处理一个三元组。我们添加三元组

    :Tom :likes :Anna
    :Tom :age 35
    

    然后再次打印出本体以确保添加了断言。由于您已经获得了 RDFTriples,您应该能够提取 handle() 需要的参数。在处理三元组之前,本体包含:

    <NamedIndividual rdf:about="http://example.org/Tom"/>
    

    然后:

    <NamedIndividual rdf:about="http://example.org/Tom">
      <example:age rdf:datatype="http://www.w3.org/2001/XMLSchema#integer">35</example:age>
      <example:likes rdf:resource="http://example.org/Anna"/>
    </NamedIndividual>
    

    代码如下:

    import java.io.Reader;
    
    import org.coode.owlapi.rdfxml.parser.OWLRDFConsumer;
    import org.semanticweb.owlapi.apibinding.OWLManager;
    import org.semanticweb.owlapi.model.IRI;
    import org.semanticweb.owlapi.model.OWLDataFactory;
    import org.semanticweb.owlapi.model.OWLDataProperty;
    import org.semanticweb.owlapi.model.OWLEntity;
    import org.semanticweb.owlapi.model.OWLNamedIndividual;
    import org.semanticweb.owlapi.model.OWLObjectProperty;
    import org.semanticweb.owlapi.model.OWLOntology;
    import org.semanticweb.owlapi.model.OWLOntologyCreationException;
    import org.semanticweb.owlapi.model.OWLOntologyLoaderConfiguration;
    import org.semanticweb.owlapi.model.OWLOntologyManager;
    import org.semanticweb.owlapi.model.OWLOntologyStorageException;
    
    import uk.ac.manchester.cs.owl.owlapi.turtle.parser.TurtleParser;
    
    
    public class ExampleOWLRDFConsumer {
        public static void main(String[] args) throws OWLOntologyCreationException, OWLOntologyStorageException {
            // Create an ontology.
            OWLOntologyManager manager = OWLManager.createOWLOntologyManager();
            OWLDataFactory factory = manager.getOWLDataFactory();
            OWLOntology ontology = manager.createOntology();
    
            // Create some named individuals and an object property.
            String ns = "http://example.org/";
            OWLNamedIndividual tom = factory.getOWLNamedIndividual( IRI.create( ns+"Tom" ));
            OWLObjectProperty likes = factory.getOWLObjectProperty( IRI.create( ns+"likes" ));
            OWLDataProperty age = factory.getOWLDataProperty( IRI.create( ns+"age" ));
            OWLNamedIndividual anna = factory.getOWLNamedIndividual( IRI.create( ns+"Anna" ));
    
            // Add the declarations axioms to the ontology so that the triples involving
            // these are understood (otherwise the triples will be ignored).
            for ( OWLEntity entity : new OWLEntity[] { tom, likes, age, anna } ) {
                manager.addAxiom( ontology, factory.getOWLDeclarationAxiom( entity ));
            }
    
            // Print the the ontology to see that the entities are declared. 
            // The important result is
            //  <NamedIndividual rdf:about="http://example.org/Tom"/>
            // with no properties
            manager.saveOntology( ontology, System.out );
    
            // Create an OWLRDFConsumer for the ontology.  TurtleParser implements AnonymousNodeChecker, so 
            // it was a candidate for use here (but I make no guarantees about whether it's appropriate to 
            // do this).  Since it won't be reading anything, we pass it a null InputStream, and this doesn't
            // *seem* to cause any problem.  Hopefully the default OWLOntologyLoaderConfiguration is OK, too.
            OWLRDFConsumer consumer = new OWLRDFConsumer( ontology, new TurtleParser((Reader) null), new OWLOntologyLoaderConfiguration() );
    
            // The consumer handles (IRI,IRI,IRI) and (IRI,IRI,OWLLiteral) triples.
            consumer.handle( tom.getIRI(), likes.getIRI(), anna.getIRI() );
            consumer.handle( tom.getIRI(), age.getIRI(), factory.getOWLLiteral( 35 ));
    
            // Print the ontology to see the new object and data property assertions.  The import contents is
            // still Tom: 
            //   <NamedIndividual rdf:about="http://example.org/Tom">
            //     <example:age rdf:datatype="http://www.w3.org/2001/XMLSchema#integer">35</example:age>
            //     <example:likes rdf:resource="http://example.org/Anna"/>
            //  </NamedIndividual>
            manager.saveOntology( ontology, System.out );
        }
    }
    

    【讨论】:

    • 首先非常感谢您的努力。我认为你稍微误解了我在做什么,我试着更准确地说:如果你愿意,我得到的三元组是异构的。我永远不知道他们描述了什么样的关系。在您的示例中,您必须手动创建 OWLObjectProperty/OWLDataProperty/... - 类。我的问题是我事先不知道它们是什么,我希望找到一种将它们添加到现有本体的自动化方法。如果这不可能,我将不得不返回并让 JSON 生产者将关系类型添加到三元组(然后是四元组?)
    • @casualcoder 我假设它们已经在你的本体中声明了。我在此处包含它们的唯一原因是,如果 OWLRDFConsumer 无法确定应该断言的内容,它将无法处理三元组。这里的想法是,一旦你有了你的本体,你只需创建消费者并调用它的句柄方法。在此示例中,您也可以从本体加载初始文件,并使用个人的 IRI 调用句柄。此代码具有声明公理等的唯一原因是它是一个最小的工作示例。
    • @casualcoder 澄清一下,handle 方法只是 IRI,正如我们在基于 Java 的代码中看到的,您可以获得。由于您已经在某处获得了 OWLOntology ontology,您只需使用它(以及 TurtleParser 和 LoaderConfiguration)创建 OWLRDFConsumer,然后让您的 addTriple() 调用消费者的 handle() 而不是 model.add()。
    • 哦,我的错。抱歉,经过 8 小时的思考,我的大脑快要爆炸了。你是对的,我的本体中已经有了所有这些,而你的答案正是我一直在寻找的。​​span>
    • @casualcoder 很高兴听到这个消息!一个接一个地处理 OWL 要困难得多,因为这在很大程度上取决于上下文。例如,在不知道 likes 是注解还是对象属性的情况下,我们不能处理像 Tom likes Anna 这样的事情。不过,正如我们在本例中所做的那样,基于三元组的处理更适合对象和数据类型属性断言。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多