简体   繁体   English

使用耶拿将字符串内插到SPARQL查询中

[英]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接受两个必需参数和一个可选参数:

  1. a string (the text) 字符串(文本)
  2. another string (the pattern) 另一个字符串(模式)
  3. (optional) a string containing flags (eg, "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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM