I am trying to get the URI from the a resource in Java, but it is always null
. Right now, I am trying this:
for ( ; rs.hasNext() ; ) {
QuerySolution qs = rs.next();
System.out.println( qs.getLiteral("label"));
System.out.println( qs.getResource("label"));
…
The literal is returned just fine, I even tried the resource "?film", but still resource is null. Here is my SPARQL query:
PREFIX mdb: <http://data.linkedmdb.org/resource/movie/film>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?label ?film where {
?film mdb:id ?uri .
?film rdfs:label ?label .
filter regex(?label, + queryVar +
}
queryVar
is just the user input, for example "Batman".
Edit:I had an typo in my query: this was my query:
String sparqlQuery = "PREFIX mdb: http://data.linkedmdb.org/resource/movie/film" + "PREFIX rdfs: http://www.w3.org/2000/01/rdf-schema# " + "select ?label ?film" + "where " + "{ ?film mdb:id ?uri ." + "?film rdfs:label ?label . " + " }" + "";
See closely at ?film and where, they become filmwhere, thats the problem.
Thanks to Joshua I figured it out.
The documentation for QuerySolution#getResource
says
Resource getResource(String varName)
Return the value of the named variable in this binding, casting to a Resource. A return of null indicates that the variable is not present in this solution. An exception indicates it was present but not a resource.
If you're getting null
, then some value isn't present in the query solution. However, without seeing your actual query, it's impossible to tell whether you're getting empty results for some reason (e.g., the queryVar
isn't what you think it is), or not. If queryVar
is just a String without surrounding quotes, you'd end up with a query like
filter regex(?label,Batman)
instead of
filter regex(?label,"Batman")
At any rate, I modified your query to be one that we can run with Jena's command line tools:
PREFIX mdb: <http://data.linkedmdb.org/resource/movie/film>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?label ?film
where {
service <http://data.linkedmdb.org/sparql> {
?film mdb:id ?uri .
?film rdfs:label ?label .
filter regex(?label, "Batman")
}
}
When I run this, I get results like:
$ arq --query query.sparql --data data.n3
-----------------------------------------------------------------------------------------
| label | film |
=========================================================================================
| "Batman" | <http://data.linkedmdb.org/resource/film/2> |
| "Batman" | <http://data.linkedmdb.org/resource/film/3> |
| "Batman & Robin" | <http://data.linkedmdb.org/resource/film/4> |
| "Batman: Mask of the Phantasm" | <http://data.linkedmdb.org/resource/film/737> |
| "Batman: Mystery of the Batwoman" | <http://data.linkedmdb.org/resource/film/974> |
| "Batman Beyond: Return of the Joker" | <http://data.linkedmdb.org/resource/film/1802> |
| "Batman & Mr. Freeze: SubZero" | <http://data.linkedmdb.org/resource/film/2124> |
-----------------------------------------------------------------------------------------
in which label
and film
are always bound. All of the labels are literals, so you should be able to do
qs.getLiteral("label")
and get a literal. It sounds more like you want the URI of the film
variable, which you would do with
qs.getResource("film").getURI()
You could, of course, use toString()
afterward if you want the URI string.
As an aside, rather than doing
"filter(?label, " + queryVar + "…"
you might want to consider using a ParameterizedSparqlString to safely substitute the queryVar in. Otherwise, what happens with queryVar
is something like
"\"Batman\") UNION { ?film hasPassword ?label }"
and it gets substituted in? You suddenly leak a bunch of information. Even if nothing sensitive gets out, you could still end up causing a big load on the SPARQL endpoint, effectively launching a denial-of-service attack.