How to add RDF triples to an OWLOntology?

◇◆丶佛笑我妖孽 提交于 2019-12-01 21:34:06

问题


I have some data coming in from a RabbitMQ. The data is formatted as triples, so a message from the queue could look something like this:

:Tom foaf:knows :Anna

where : is the standard namespace of the ontology into which I want to import the data, but other prefixes from imports are also possible. The triples consist of subject, property/predicate and object and I know in each message which is which.

On the receiving side, I have a Java program with an OWLOntology object that represents the ontology where the newly arriving triples should be stored temporarily for reasoning and other stuff. I kind of managed to get the triples into a Jena OntModel but that's where it ends. I tried to use OWLRDFConsumer but I could not find anything about how to apply it.

My function looks something like this:

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());
}

I did the substring operations because the RDFTriple class adds <> around the arguments of the triple and the constructor of Statement fails as a consequence.

If anybody could point me to an example that would be great. Maybe there's a much better way that I haven't thought of to achieve the same thing?


回答1:


It seems like the OWLRDFConsumer is generally used to connect the RDF parsers with OWL-aware processors. The following code seems to work, though, as I've noted in the comments, there are a couple of places where I needed an argument and put in the only available thing I could.

The following code: creates an ontology; declares two named individuals, Tom and Anna; declares an object property, likes; and declares a data property, age. Once these are declared we print the ontology just to make sure that it's what we expect. Then it creates an OWLRDFConsumer. The consumer constructor needs an ontology, an AnonymousNodeChecker, and an OWLOntologyLoaderConfiguration. For the configuration, I just used one created by the no-argument constructor, and I think that's OK. For the node checker, the only convenient implementer is the TurtleParser, so I created one of those, passing null as the Reader. I think this will be OK, since the parser won't be called to read anything. Then the consumer's handle(IRI,IRI,IRI) and handle(IRI,IRI,OWLLiteral) methods are used to process triples one at a time. We add the triples

:Tom :likes :Anna
:Tom :age 35

and then print out the ontology again to ensure that the assertions got added. Since you've already been getting the RDFTriples, you should be able to pull out the arguments that handle() needs. Before processing the triples, the ontology contained:

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

and afterward this:

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

Here's the code:

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 );
    }
}



回答2:


In ONT-API, which is an extended Jena-based implementation of OWL-API, it is quite simple:

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

For more information see ONT-API wiki, examples



来源:https://stackoverflow.com/questions/17468984/how-to-add-rdf-triples-to-an-owlontology

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!