1

I have a TTL with something like

ex:isDataProperty rdf:type owl:DatatypeProperty .

ex:Article  a       owl:Class ;
        owl:hasKey  ( ex:isDataProperty ) .

And when I load the model with RDF4J (as a TreeModel) then try to filter to extract the properties annotated with haskey fails (just returns empty list result)

Some samples that return data:

val dataProperties = model.filter(null, RDF.TYPE, OWL.DATATYPEPROPERTY).subjects().asScala
val classes = model.filter(null, RDF.TYPE, OWL.CLASS).subjects().asScala

The sample I want, that doesn't return data:

    val propertiesWithKeys = model.filter(null, RDF.PROPERTY, OWL.HASKEY).subjects().asScala

I have tried a few variations of the previous one using RDF.TYPE or RDF.Value. (instead of RDF.PROPERTY)

Jeen Broekstra
  • 21,642
  • 4
  • 51
  • 73
  • 1
    Why do you use `model.filter(null, RDF.PROPERTY, OWL.HASKEY)`? I mean, the predicate itself is `OWL.HASKEY`, so it should be `model.filter(null, OWL.HASKEY, null)` to get all triples with this predicate – UninformedUser Jul 10 '19 at 16:56
  • 1
    and the property isn't "annotated" with it. The property is used as key. The RDF triple is `ex:Article owl:hasKey ( ex:isDataProperty ) .` - that also means, the property itself is an object in the triple which in fact is a list because it can be a composite key in OWL. So `model.filter(null, OWL.HASKEY, null).objects()` will lead to nodes representing RDF collections. How to convert back those RDF collections can be found here: https://rdf4j.eclipse.org/documentation/programming/model/#rdf-collections - so use `RDFCollections.asValues` or `RDFCollections.getCollection` with the arguments – UninformedUser Jul 10 '19 at 17:04

1 Answers1

1

The thing you're after is any subject that has a owl:hasKey property, regardless of value. So both the subject and the object are wildcards, you just want to filter by property name. The way to do that is like this:

model.filter(null, OWL.HASKEY, null)

Now, furthermore you say that you want to know the properties that have been used as annotation using this owl:hasKey property. In your example, that would be ex:isDataProperty. Note that in your model, this is not the subject of the owl:hasKey relation - it's in the object values:

model.filter(null, OWL.HASKEY, null).objects()

To further complicate matters, the object values in your example are not simply single values. Instead, each class is annotated using a list of properties, so the object value is a list object (a.k.a. an RDF Collection). To process this list, there are some utility methods provided by the Models and RDFCollections classes.

For each of the objects you can do this to get the actual list of values:

RDFCollections.asValues(model, objectNode, new ArrayList<Value>())

(where objectNode is one of the values that .objects() returned)

Edit since objects() returns objects of type Value and RDFCollections expects a Resource, you'll either have to do a cast, or if you want to do all of this in a fluent way, you can use Models.objectResources instead. The whole thing then becomes:

Models.objectResources(model.filter(null, OWL.HASKEY, null))
        .asScala.map(o => RDFCollections.asValues(model, o, new ArrayList[Value]()));

(I may have the Scala-specific bits of this wrong, but you get the gist hopefully)

For more information on how to work with the rdf4j Model API and with RDF Collections, see the rdf4j documentation.

Jeen Broekstra
  • 21,642
  • 4
  • 51
  • 73
  • Thanks, btw, when I use model.filter(null, OWL.HASKEY, null).subjects().asScala.map(o => org.eclipse.rdf4j.model.util.RDFCollections.asValues(model, o, new java.util.ArrayList[org.eclipse.rdf4j.model.Value]())) I get an error of "rdf4j list not well formed rdf:first statement missing", any tip? – Fernando Gonzalez Sanchez Jul 11 '19 at 04:17
  • thanks, the prob is with .objects doesn't compile, RDFCollection.asValues 2nd arg expect a org.eclipse.rdf4j.model.Resource not a Value – Fernando Gonzalez Sanchez Jul 11 '19 at 05:04
  • `Resource` is a subclass of `Value`. You'll have to cast it. Or use [`Models.objectResources(model.filter(null, OWL.HASKEY, null))`](https://rdf4j.eclipse.org/javadoc/latest/org/eclipse/rdf4j/model/util/Models.html#objectResources-org.eclipse.rdf4j.model.Model-) instead. – Jeen Broekstra Jul 11 '19 at 06:02
  • Right both Resource & Value have the same members. Thanks. – Fernando Gonzalez Sanchez Jul 11 '19 at 07:36