rdf4j filter model by rdf:id

336 views Asked by At

Is it possible in rdf4j to filter a model by their rdf:id? I tried already the following approach:

model.filter(res, null, null)

But with this, I also get all occurrences of rdf:resource and rdf:about. At the moment I filter first the whole model for all occurrences of the wanted type (which returns a model). And then I filter this model for the resource and with this resource, I filter the whole model for the needed model-part:

Model typeModel = model.filter(null, RDF.TYPE, iri);
// the following obj contains only the id (found in an rdf:about or rdf:resource)
// normally I also do some checks before .iterator().next()
Resource res = typeModel.filter((Resource) obj, null, null).subjects().iterator().next();
Model resModel = model.filter(res, null, null);

I think my solution creates too much overhead because I would also need a typeModel for each Type. Is there another way of filtering the model for the rdf:id?

UPDATE:

Here is a short example: I need to find the ACLineSegment with the help of the rdf:resource of the Terminal.ConductingEquipment.

<cim:Terminal rdf:ID="_8fd6a918-5a8d-42f2-ae19-3ee77bc76911">
  <cim:ACDCTerminal.sequenceNumber>2</cim:ACDCTerminal.sequenceNumber>
  <cim:IdentifiedObject.name>XXXX</cim:IdentifiedObject.name>
  <cim:Terminal.ConductingEquipment rdf:resource="#_50c99578-6e17-45e1-a113-a4a28d643b40" />
  <cim:Terminal.ConnectivityNode rdf:resource="#_eefd8021-6f56-4154-9b2b-9e275c0f43d0" />
  <cim:Terminal.phases rdf:resource="http://iec.ch/TC57/2013/CIM-schema-cim16#PhaseCode.ABC" />
</cim:Terminal>
<cim:ACLineSegment rdf:ID="_50c99578-6e17-45e1-a113-a4a28d643b40">
  <cim:ACLineSegment.b0ch>5.44828e-5</cim:ACLineSegment.b0ch>
  <cim:ACLineSegment.bch>5.44828e-5</cim:ACLineSegment.bch>
  ....
</cim:ACLineSegment>
1

There are 1 answers

0
UninformedUser On BEST ANSWER

You should never read your RDF document in RDF/XML syntax - as you already recognized, this is not really human-readable and designed as interchange format for machines. An RDF dataset contains a set of triples, a good format to see those triples is N-Triples or Turtle.

I converted your data to N-Triples (I assumed http://example.org/ to be the namspace of the prefix cim and http://example.org/data as base URI):

<http://example.org/data#_8fd6a918-5a8d-42f2-ae19-3ee77bc76911> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/Terminal> .
<http://example.org/data#_8fd6a918-5a8d-42f2-ae19-3ee77bc76911> <http://example.org/ACDCTerminal.sequenceNumber> "2" .
<http://example.org/data#_8fd6a918-5a8d-42f2-ae19-3ee77bc76911> <http://example.org/IdentifiedObject.name> "XXXX" .
<http://example.org/data#_8fd6a918-5a8d-42f2-ae19-3ee77bc76911> <http://example.org/Terminal.ConductingEquipment> <http://example.org/data#_50c99578-6e17-45e1-a113-a4a28d643b40> .
<http://example.org/data#_8fd6a918-5a8d-42f2-ae19-3ee77bc76911> <http://example.org/Terminal.ConnectivityNode> <http://example.org/data#_eefd8021-6f56-4154-9b2b-9e275c0f43d0> .
<http://example.org/data#_8fd6a918-5a8d-42f2-ae19-3ee77bc76911> <http://example.org/Terminal.phases> <http://iec.ch/TC57/2013/CIM-schema-cim16#PhaseCode.ABC> .
<http://example.org/data#_50c99578-6e17-45e1-a113-a4a28d643b40> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/ACLineSegment> .
<http://example.org/data#_50c99578-6e17-45e1-a113-a4a28d643b40> <http://example.org/ACLineSegment.b0ch> "5.44828e-5" .
<http://example.org/data#_50c99578-6e17-45e1-a113-a4a28d643b40> <http://example.org/ACLineSegment.bch> "5.44828e-5" .

You can see, in fact, there are 9 RDF triples.

Your task was

find the ACLineSegment with the help of the rdf:resource of the Terminal.ConductingEquipment

This formulation sounds super artificial and is not what a human would say when querying the data. I tried to translate it (I'm not used to the domain of the data):

Given the Terminal, give me its Terminal.ConductingEquipment element

So what do we have so far?

  1. We have the terminal, i.e. we have http://example.org/data#_8fd6a918-5a8d-42f2-ae19-3ee77bc76911.
  2. We also know the predicate for which you want to get the object, it is cim:ACLineSegment

What does it mean? We have subject and predicate of an RDF triple and want to get its object. Right now, you should already know the solution, simply filter the model by subject and predicate, i.e.

ValueFactory vf = SimpleValueFactory.getInstance();

// the subject which is the IRI of the terminal
IRI s = vf.createIRI("**http://example.org/data#_8fd6a918-5a8d-42f2-ae19-3ee77bc76911**");

// the predicate which is the IRI of the property cim:Terminal.ConductingEquipment
IRI p = vf.createIRI("http://example.org/Terminal.ConductingEquipment");

// filter by subject and predicate
Model filteredModel = model.filter(s, p, null);

// get the object, if one exists
Resource acLineSegment = Models.objectResource(filteredModel).orElse(null);

Don't forget, that I assumed http://example.org/data as base URI of the RDF/XML document and http://example.org/ as the namespace of the prefix cim - you should replace this in the code above with the proper values.