[英]Interpolate a string into a SPARQL query with Jena
I want to create a SPARQL queries from Java (particularly, Jena and ARQ). 我想从Java(特别是Jena和ARQ)创建SPARQL查询。 I want to make it possible for a user who may not know anything about SPARQL to make a query by just writing (eg, in a console from Eclipse) the word he wants to search for.
我想让可能对SPARQL一无所知的用户仅通过写(例如,在Eclipse的控制台中)他要搜索的词来进行查询。 The following code gives an example of what I'm looking for.
以下代码提供了我要寻找的示例。 How can I interpolate the string
word
into the query? 如何将字符串
word
插入查询中?
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();
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): 会生成SPARQL文本,例如(假设
word
是香蕉):
Filter (regex(?a = banana))
That's not how regex
is used in SPARQL. 这不是在SPARQL中使用
regex
方式。 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. 并将其粘贴到sparql.org的验证器中 ,您将看到这是一个语法错误。 However, the documentation for
regex
has some examples. 但是,
regex
的文档中有一些示例。 regex
takes two required arguments, and one optional argument: regex
接受两个必需参数和一个可选参数:
"i"
, for case insensitive matching) "i"
,用于不区分大小写的匹配) To use regex
, you'd need to do something like: 要使用
regex
,您需要执行以下操作:
"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 当然,这为您带来了经典的注入问题,因为如果
word
包含"
,则会遇到问题。这就是为什么应该使用ParameterizedSparqlString ;您可以
filter(regex(?a,?word))
and then just replace ?word
with the value of word
, and all the escaping will be handled correctly. 然后只需将
?word
替换为word
,所有转义都将得到正确处理。
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 要将值包含在查询中,最好使用QuerySolutionMap将SPARQL参数绑定到某个值,如http://jena.apache.org/documentation/query/parameterized-sparql-strings.html所述 。用户中的所有特殊字符都提供了字符串(“最重要”),并使用Java字符串串联来包含值。以上示例将变为
... WHERE {
?subject pred:somePred ?value
}
Later you would bind the name "value" to the user provided value. 稍后,您将名称“值”绑定到用户提供的值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.