0

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.

Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353
miniHessel
  • 778
  • 4
  • 15
  • 39
  • Now that you've found a solution, perhaps you can update the SPARQL query in the question to reflect what the _actual_ problem was (i.e., update the question to be `select ?label ?filmwhere { ... }` or `select ?label where { ... }`, so that we can create an answer that addresses it? – Joshua Taylor Sep 10 '13 at 17:35

1 Answers1

2

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.

Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353
  • If I use Label I get the following error com.hp.hpl.jena.rdf.model.impl.LiteralImpl cannot be cast to com.hp.hpl.jena.rdf.model.Resource By the way, isnt it getURI? – miniHessel Sep 10 '13 at 16:00
  • You're right; it should be getURI, and I've updated my answer. The exception is expected, as per the javadoc for getResource: "An exception indicates it was present but not a resource." A Literal _is not_ a Resource. A Resource _is not_ a Literal. You can do `qs.getResource("film")` and get a resource, since those values are resources, and you can do `qs.getLiteral("label")` and get a literal, since those values are literals. – Joshua Taylor Sep 10 '13 at 16:06
  • I did have a typo in my code, too. I meant `qs.getResource("film").getURI()`, not `qs.getResource("label").getURI()`. Sorry. I did say though, that "you want the URI of the film variable, which you would do with", which should have suggested that `"label"` was a copy/paste typo for `"film"`. – Joshua Taylor Sep 10 '13 at 16:08
  • @user2715404 The [pastebin code](http://pastebin.com/L7Qs3Q1A) is very different from the code in the question. It only selects `label` (it has `select ?label where`, with no `?film`), so, just as the documentation says, you get "null [which] indicates that the variable is not present in this solution." – Joshua Taylor Sep 10 '13 at 16:15
  • Okay, I have now changed to your query, but still I get the null pointer.. Could you perhaps see my code? Sorry, its messy: http://pastebin.com/eYnecZ54 – miniHessel Sep 10 '13 at 16:25
  • Ye sorry about that first pastebin, fixed to ?label ?film, and it worked great ! Now I only need to find whats wrong in my code.. – miniHessel Sep 10 '13 at 16:25
  • I don't see any SPARQL query in that latest pastebin, http://pastebin.com/eYnecZ54, just `sparqlQuery = m.getSarqlQuery(searchText);`. – Joshua Taylor Sep 10 '13 at 16:37
  • The sparql query is identical to yours : String sparqlQuery = "PREFIX mdb: " + "PREFIX rdfs: " + "select ?label ?film" + "where " + "{ ?film mdb:id ?uri ." + "?film rdfs:label ?label . " + " }" + ""; – miniHessel Sep 10 '13 at 16:41
  • m is just a class where I have stored the query – miniHessel Sep 10 '13 at 16:41
  • It'd be much more helpful to see that in pastebin than in the comments. E.g., something like `"select ?label ?film" + "where "+` looks like you'll end up with `select ?label ?filmwhere {` with a variable named `filmwhere` which won't be helpful. (It's still legal though, since the `where` is optional, and `select ... where { ... }` is equivalent to `select ... { ... }`. This is also a good reason for putting newlines in your SPARQL queries with `\n`. Also a good reason for printing your SPARQL queries and putting them in the question so that we can _exactly_ what your query is. :) – Joshua Taylor Sep 10 '13 at 16:45
  • How embarrassing, you are in fact right. I am sorry, spent so many hours in front of the code that I obviously went blind.. – miniHessel Sep 10 '13 at 17:24