Andy,
Thanks for your comprehensive explanation. Now I've implemented
PathParser which correctly builds a SPARQL query. But the generated
ResultSet seems to behave differently from that generated by the same
query from QueryFactory.create(queryStr) on the same data. The query
created by PathParser & Co.[1] runs into an Exception on
ResultSet.hasNext() (Stacktrace below [2]).
For context: I am doing this partly to learn something. The actual task
performed is retrieving a model from a provided URI and then follow a
path from that model. The program retrieves necessary additional the
data from object URIs on it's 'way'. So a simple alternative could be
using a SimpleSelector on the last predicate in the PropertyPath as it
is iterated anyway for data retrieval and more complex Paths are not
necessary.
Best Regards
Andreas
[1] Here's the code using your hint for parsing the PropertyPath:
private Query buildQuery(final String propertyPath) {
/* Example query:
SELECT *
WHERE
{
<http://opacplus.bsb-muenchen.de/title/BV001614824>
<http://purl.org/dc/terms/creator>/<http://d-nb.info/standards/elementset/gnd#preferredName>
?preferredName
}
*/
final ElementPathBlock pathBlock = new ElementPathBlock();
pathBlock.addTriplePath(
new TriplePath(
NodeFactory.createURI(this.titleUri),
PathParser.parse(propertyPath, PREFIXMAPPING),
NodeFactory.createVariable(VAR_PREFERRED_NAME)
)
);
return buildSelectQuery(pathBlock);
}
private Query buildSelectQuery(final
org.apache.jena.sparql.syntax.Element queryBlock) {
final Query query = new Query();
query.setQuerySelectType();
query.setQueryResultStar(true);
query.setQueryPattern(queryBlock);
return query;
}
[2] Stacktrace:
org.apache.jena.sparql.core.Var$NotAVariableException: Node_variable
(not a Var) found
at org.apache.jena.sparql.core.Var.isVar(Var.java:146)
at
org.apache.jena.sparql.engine.iterator.QueryIterTriplePattern$TripleMapper.substitute(QueryIterTriplePattern.java:87)
at
org.apache.jena.sparql.engine.iterator.QueryIterTriplePattern$TripleMapper.<init>(QueryIterTriplePattern.java:69)
at
org.apache.jena.sparql.engine.iterator.QueryIterTriplePattern.nextStage(QueryIterTriplePattern.java:49)
at
org.apache.jena.sparql.engine.iterator.QueryIterRepeatApply.makeNextStage(QueryIterRepeatApply.java:108)
at
org.apache.jena.sparql.engine.iterator.QueryIterRepeatApply.hasNextBinding(QueryIterRepeatApply.java:65)
at
org.apache.jena.sparql.engine.iterator.QueryIteratorBase.hasNext(QueryIteratorBase.java:111)
at
org.apache.jena.sparql.engine.iterator.QueryIterBlockTriples.hasNextBinding(QueryIterBlockTriples.java:63)
at
org.apache.jena.sparql.engine.iterator.QueryIteratorBase.hasNext(QueryIteratorBase.java:111)
at
org.apache.jena.sparql.engine.iterator.QueryIteratorWrapper.hasNextBinding(QueryIteratorWrapper.java:39)
at
org.apache.jena.sparql.engine.iterator.QueryIteratorBase.hasNext(QueryIteratorBase.java:111)
at
org.apache.jena.sparql.engine.iterator.QueryIteratorWrapper.hasNextBinding(QueryIteratorWrapper.java:39)
at
org.apache.jena.sparql.engine.iterator.QueryIteratorBase.hasNext(QueryIteratorBase.java:111)
at
org.apache.jena.sparql.engine.ResultSetStream.hasNext(ResultSetStream.java:74)
at
org.apache.jena.sparql.engine.ResultSetCheckCondition.hasNext(ResultSetCheckCondition.java:59)
[...]
>>> Andy Seaborne <[email protected]> 03.03.16 11.57 Uhr >>>
SSE, = SPARQL S-Expressions, is not SPARQL syntax. It is used
intrernally for read/write all sorts of datastructures in its own
unifying syntax.
http://jena.apache.org/documentation/notes/sse.html
You need to invoke the SPARQL parser if you want to write in SPARQL
syntax.
This happens to be wrapped up for convenience (internal API) in
'PathParser':
Illustration of the formats:
org.apache.jena.sparql.core.Prologue prologue
= new Prologue(SSE.defaultPrefixMapWrite) ;
Path path = PathParser.parse("^:r|:p*/:q",
SSE.defaultPrefixMapRead) ;
System.out.println(path) ;
String x = WriterPath.asString(path, prologue) ;
System.out.println(x) ;
Path path2 = SSE.parsePath(x) ;
System.out.println(path2) ;
^<http://example/r>|((<http://example/p>)*/<http://example/q>)
in SSE is:
(alt
(reverse <http://example/r>)
(seq (path* <http://example/p>) <http://example/q>))
Andy
On 02/03/16 14:13, Andreas Kahl wrote:
> Hello,
>
> I would like to create a SPARQL query using a property path:
> SELECT * WHERE {
> <http://exampleUri> dct:creator/gndo:preferredNameForThePerson ?o
> }
>
> I am trying to create that query via the Jena API, but parsing the
> PropertyPath with SSE.parsePath(String,PrefixMapping) fails.
> This is my call:
> String propertyPath = "dct:creator/gndo:preferredNameForThePerson";
> Path parsedPropertyPath = SSE.parsePath(propertyPath, PREFIXMAPPING);
>
> The parsing fails with
> org.apache.jena.sparql.ARQException: Not a list:
> dct:creator/gndo:preferredNameForThePerson
>
> I cannot find any working examples. Is my PropertyPath wrong, or does
> Jena require a special syntax? Should I use another method to obtain a
> Path object?
> As a context I have appended my complete methods for creating the
SPARQL
> query.
>
> Thanks for your advice.
>
> Regards
> Andreas
>
> P.S. Here are my SPARQL creator methods
> private Query buildQuery(final String propertyPath) {
> // dct:creator/gndo:preferredNameForThePerson
> ElementTriplesBlock triplesBlock = new ElementTriplesBlock();
> Path parsedPropertyPath = SSE.parsePath(propertyPath,
> PREFIXMAPPING);
> triplesBlock.addTriplePath(
> new
> TriplePath(NodeFactory.createURI(this.titleUri.toString()),
> parsedPropertyPath,
> NodeFactory.createVariable("preferredName"))
> );
> final Query query = buildSelectQuery(triplesBlock);
> System.out.println(query.serialize());
> return query;
> }
>
> private Query buildSelectQuery(final ElementTriplesBlock
queryBlock) {
> final Query query = new Query();
> query.setPrefixMapping(PREFIXMAPPING);
> query.setQuerySelectType();
> query.setQueryResultStar(true);
> query.setDistinct(true);
> query.setQueryPattern(queryBlock);
> return query;
> }