0

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
  }
Hervé Girod
  • 465
  • 3
  • 12
  • what do you mean by limitations in Jena? Also, classes do not have properties in OWL, so it's unclear what OWL axioms you're talking about. – UninformedUser Jun 20 '23 at 09:32
  • That said, both, Jena and RDF4J are primarily RDF frameworks - searching for OWL axioms is querying or traversing the RDF serialization of those: https://www.w3.org/TR/owl2-mapping-to-rdf/ - obviously, for complex class expressions this can be cumbersome, as you have to traverse blank nodes in the graph – UninformedUser Jun 20 '23 at 09:34
  • I was taking about OWL2 which Jena does not support If i'm not mistaken. Also what I would klike to get is: the list of Classes, the list of dataproperties and Objectpropeties accessed thorugh a class, etc.. I was able to do that with a relatively simple approach in Jena. I could update my question to explain how I did it in Jena. – Hervé Girod Jun 20 '23 at 09:34
  • there is no OWL 2 support for the Jena Ontology Layer, yes - but that does not prevent you from navigating the RDF graph. That is the same you'Re doing now in RDF4J - both are designed for RDF, first class citizens are RDF resources and RDF triples, not OWL axioms. There is a reason for having e.g. OWL API which works natively on OWL axiom level. And there is a bridge between Jena and OWL API, dubbed Ont API which you could use – UninformedUser Jun 20 '23 at 09:36
  • "the list of dataproperties and Objectpropeties accessed thorugh a class" - that is a vague description, just speak in OWL terms, what kind of OWL axioms and what kind of OWL class expressions are you talking about. As I said, https://www.w3.org/TR/owl2-mapping-to-rdf/ shows how each OWL construct is represented in RDF. So that is the way to go for you if you stick to Jena or RDF4J. Or you just use OWL API resp. the bridge to Jena via Ont API – UninformedUser Jun 20 '23 at 09:38
  • I just clarified my question by showing the Jena code, which works very well in my use cases. – Hervé Girod Jun 20 '23 at 16:39
  • So I'm asking how (and if) it is possible to do the same thing using RDF4J. – Hervé Girod Jun 21 '23 at 08:35

1 Answers1

1

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.

Jeen Broekstra
  • 21,642
  • 4
  • 51
  • 73