Jena: Property Paths in Query Programming
I am trying to use the API that Jena offers to program SPARQL queries. To keep it simple, I would like something like:
SELECT *
WHERE {
?typ rdfs:subClassOf+ myns:SomeType .
}
The problem is with rdfs: subClassOf + which uses property paths. I am trying to build a query like this:
query = new Query();
query.setQuerySelectType();
query.addResultVar("typ");
ElementTriplesBlock triplePattern = new ElementTriplesBlock();
Node typ = NodeFactory.createVariable("typ");
Node sometype = ...; // Assume OK
triplePattern.addTriple(new Triple(typ,
ResourceFactory.createProperty(RDFS.subClassOf.getURI() + "+").asNode(),
sometype));
query.setQueryPattern(triplePattern);
If I didn't have a property path, that is, in SPARQL it only said rdfs: subClassOf , I could go with:
triplePattern.addTriple(new Triple(typ,
RDFS.subClassOf.asNode(),
sometype));
What works. However, I am unable to specify the path modifier in the URI to create the property, as I am getting:
Caused by: com.hp.hpl.jena.shared.InvalidPropertyURIException: http://www.w3.org/2000/01/rdf-schema#subClassOf+
at com.hp.hpl.jena.rdf.model.impl.PropertyImpl.checkLocalName(PropertyImpl.java:67)
at com.hp.hpl.jena.rdf.model.impl.PropertyImpl.<init>(PropertyImpl.java:56)
at com.hp.hpl.jena.rdf.model.ResourceFactory$Impl.createProperty(ResourceFactory.java:296)
at com.hp.hpl.jena.rdf.model.ResourceFactory.createProperty(ResourceFactory.java:144)
... (test class)
So the question is, how can I specify such a request to Jena via the Java API. I know I can make a request from a string with property path syntax, but not when creating the request programmatically.
source to share
I guess I found it after doing a bit of tinkering.
First, you need to use ElementPathBlock if the WHERE {...} part will use any paths, since trying to add a path to the ElementTripleBlock will throw an exception. Then, instead of adding a triplet, you can add a TriplePath. Code:
ElementPathBlock triplePattern = new ElementPathBlock();
Node typ = NodeFactory.createVariable("typ");
Node sometype = ...; // Assume OK
// This represents rdfs:subClassOf+
Path pathSubClassOfPlus = PathFactory.pathOneOrMore1(
PathFactory.pathLink(RDFS.subClassOf.asNode())
);
// This represents the SPARQL: ?typ rdfs:subClassOf+ sometype .
TriplePath subClassOfPlus = new TriplePath(typ, pathSubClassOfPlus, sometype)
triplePattern.addTriplePath(subClassOfPlus);
// ... One can also add regular Triple instances afterwards
query.setQueryPattern(triplePattern);
source to share