1

I want to create a SPARQL queries from Java (particularly, Jena and ARQ). I want to make it possible for a user who may not know anything about SPARQL to make a query by just writing (e.g., in a console from Eclipse) the word he wants to search for. The following code gives an example of what I'm looking for. How can I interpolate the string word into the query?

String word="someThingToFind"; // a variable entered by the user who want to request my data
String queryString =
"Select ?a ?b"+
    " Where { ...."+
    " Filter (regex(?a = ".concat(word)+ "))"+// word is the String variable 
" }";

Query query = QueryFactory.create(queryString, Syntax.syntaxARQ);   
QueryExecution qe = QueryExecutionFactory.create(query, model);
ResultSet results = qe.execSelect();
ResultSetFormatter.out(System.out, results, query);
qe.close();
Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353
jojo
  • 333
  • 2
  • 13
  • possible duplicate of [Parameterized SPARQL query with JENA](http://stackoverflow.com/questions/9729659/parameterized-sparql-query-with-jena) – RobV Nov 26 '13 at 17:20
  • No, I do not think so, because I've tried this solution, but it did not work, even I've tried to concatenate the query with my String variable , but it did not work too. – jojo Nov 26 '13 at 17:55
  • 2
    @jojo Reasons for closing questions include: "Questions asking for code must demonstrate a minimal understanding of the problem being solved. **Include attempted solutions, why they didn't work, and the expected results.**" If you already tried something that's a _known solution_ (i.e., the answer to the other problem), can you show that attempt and what didn't work about it? – Joshua Taylor Nov 26 '13 at 20:02

2 Answers2

5

This line in your code

Filter (regex(?a = ".concat(word)+ "))"+// word is the String variable

will produce SPARQL text like (assuming that word is banana):

Filter (regex(?a = banana))

That's not how regex is used in SPARQL. When you're trying to parameterize queries, it's a good idea to make sure that you've got a working form to begin with, and then you can start making parts of it parameterized. Sure enough, if you take a stripped down version of your query:

select * where { filter(regex(?a = "banana")) }

and paste it into the sparql.org's validator, you'll see that it's a syntax error. However, the documentation for regex has some examples. regex takes two required arguments, and one optional argument:

  1. a string (the text)
  2. another string (the pattern)
  3. (optional) a string containing flags (e.g., "i", for case insensitive matching)

To use regex, you'd need to do something like:

"filter(regex(?a, \"" + word + "\"))"

so that you can get

filter(regex(?a,"banana"))

in the query. Of course, this opens you up to a classic injection problems, since you've got a problem if word contains ". This is why you should use a ParameterizedSparqlString; you can have

filter(regex(?a,?word))

and then just replace ?word with the value of word, and all the escaping will be handled correctly.

Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353
0

There are two options to include parameters in query strings. You don't need to use the filter unless you want to use more advanced functions, like patterns. When selecting triples, you can just use the user provided value as the triple's object:

... WHERE {
    ?subject pred:somePred "value"
}

To include the value in the query it is best to use a QuerySolutionMap to bind a SPARQL parameter to some value, as documented on http://jena.apache.org/documentation/query/parameterized-sparql-strings.html Otherwise, escape all special characters in the user provided string (" most important) and use Java string concatenation to include the value. The above example would become

... WHERE {
    ?subject pred:somePred ?value
}

Later you would bind the name "value" to the user provided value.

antiguru
  • 1,101
  • 11
  • 18
  • Thank you, but I'm afraid that I did not understand, would you explain more please, knowing that the filter is important for my queries, the above example is just for explanation, and I've tried to concatenate the query with the word but it did not work, may be I do not write it in the correct way.. – jojo Nov 26 '13 at 18:01