rdfowlrdf4j

Getting all the Owl classes in an Owl/RDF schema using RDF4J


I have developed a library which shows the graph of an Owl/RDF ontology using Jena, but I would like to be able to do the same thing using RDF4J because there are some limitations in Jena regarding which kind of Owl/RDF schema can be read.

I am able to get the model using this code without any problem (apparently):

  URL url = file.toURI().toURL();
  try (InputStream inputStream = url.openStream()) {
     DynamicModelFactory factory = new DynamicModelFactory();
     Model model = (Model) factory.createEmptyModel();
     RDFFormat format = Rio.getParserFormatForFileName(url.toString()).orElse(RDFFormat.RDFXML);
     RDFParser rdfParser = Rio.createParser(format);
     rdfParser.setRDFHandler(new StatementCollector(model));
     try {
        rdfParser.parse(inputStream, url.toString());
     } catch (IOException | RDFParseException | RDFHandlerException e) {
        e.printStackTrace();
     }
  }

However I want to get all the Owl classes in the model and their properties (DataProperties and ObjectProperties), and their subclasses. How can I do it using RDF4J when I have the model? Or maybe my approach is not the right one?

I tried to iterate through all the Statements in the model using:

    for (Statement st : model) {
       Value object = st.getObject();
       Resource res = st.getSubject();
       System.out.println(object + " " + res);
    }

But the Value and Resource are always SimpleIRI. How can I know that a Value or a Resource is a Class / Property, etc.. ?

To clarify my question, here is how I'm doing it using Jena:

OntModel model = createModel("OWL_MEM");
FileManager.get().readModel(model, uri.toString());
Model _model = model.getRawModel();
model = new OntModelImpl(OntModelSpec.OWL_MEM, _model);
ExtendedIterator classes = model.listClasses();
while (classes.hasNext()) {
    OntClass theOwlClass = (OntClass) classes.next();
    if (thisClass.getNameSpace() == null && thisClass.getLocalName() == null) {
       continue;
    }
    // now I have all the classes in the model
    ...
 }

And for the properties:

  ExtendedIterator properties = model.listAllOntProperties();
  while (properties.hasNext()) {
     OntProperty thisProperty = (OntProperty) properties.next();
     // and now I have the properties
  }

Solution

  • RDF4J has no direct equivalent to Jena's Ontology API (which contains the OntClass class). Instead, in RDF4J you always work with RDF only. Models are pure RDF graphs.

    That doesn't mean you can't work with OWL ontologies of course, just that you'll have to do it by thinking of it in terms of how OWL ontologies are represented in RDF. In this particular case, you can filter on type statements, e.g. like this:

    Set<Resource> owlClasses = model.filter(null, RDF.TYPE, OWL.CLASS).subjects();
    

    The members of your set will be the IRIs that identify OWL classes in your model.

    Note: RDF4J models do not do any form of reasoning or inference, so this will only work correctly if your model actually contains all the type statements that mark it as an OWL class.