Question

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.

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top