我正在尝试根据给定的查询构建一个新查询(旧查询 - 我无法更改此信息)。
假设我获得了一个简单有效的SPARQL查询SELECT ?s WHERE{ ?s ?p ?o }
。假设我创建了上述查询的jena查询对象,并在java中将查询模式作为ElementGroup获取,如下所示:
Query q = QueryFactory.create("SELECT ?s WHERE{ ?s ?p ?o }, Syntax.syntaxSPARQL_11);
ElementGroup oldQP = (ElementGroup)q.getQueryPattern();
我之前使用以下语法向旧查询模式添加新三元组的方式是:
Triple t = Triple.create(...);
oldQP.addTriplePattern(t);
但是,当您去创建新的查询对象时:
Query nq = q.cloneQuery();
nq.setQueryPattern(oldQP);
nq.setQuerySelectType();
nq.setQueryResultStar(false);
nq.addResultVar("s");
您最终会得到一个类似于
的查询SELECT ?s WHERE{
?s ?p ?o
?s2 ?p2 ?s.
}
因为它不能识别/关心第一个三元组在设置对象的QueryPattern时没有以句点结束。执行查询时,这会导致解析错误...
Encountered " <VAR1> "?s2 "" at line 10, column 3.
Was expecting one of:
"graph" ...
"optional" ...
"minus" ...
"bind" ...
"service" ...
"let" ...
"exists" ...
"not" ...
"filter" ...
"{" ...
"}" ...
";" ...
"," ...
"." ...
因为这显然是无效的SPARQL。那么,如何避免这个问题呢?如果所有三元组都有结束时间段,则不会发生此问题,但我似乎找不到任何方法来使其工作。
谢谢!
答案 0 :(得分:1)
我不确定我是否完全按照你的问题
第二个查询来自哪里?您是否在新查询对象上调用toString()
,在这种情况下,这可能是打印查询的内部逻辑中的错误。
您还在使用什么版本的ARQ?
答案 1 :(得分:1)
所以我似乎找到了一个解决方法/解决方案。 经过调试并仔细查看由行
创建的ElementGroup
对象
ElementGroup oldQP = (ElementGroup)q.getQueryPattern();
我注意到它运行了Element对象的ArrayList(通过方法ElementGroup.getElements()
检索)。在我尝试添加三元组(通过ElementGroup.addTriplePattern(...)
方法)之前,此列表中唯一的内容是类型ElementPathBlock
的对象。好的,很酷。
接下来,我尝试通过上面的方法添加三元组,如下所示:
Triple t = Triple.create(...);
oldQP.addTriplePattern(t);
我注意到这会在ElementGroup的Elements列表中添加一个新的ElementTriplesBlock
。这似乎是罪魁祸首。所以,我的解决方案是获取最后一次出现的ElementPathBlock
,并将三元组添加到该对象而不是将它们添加到ElementGroup(从而避免将新的ElementTriplesBlock
添加到ArrayList): / p>
//same as before
Query q = QueryFactory.create("SELECT ?s WHERE{ ?s ?p ?o }, Syntax.syntaxSPARQL_11);
Query nq = q.cloneQuery();
ElementGroup oldQP = (ElementGroup)q.getQueryPattern();
Triple t = Triple.create(Var.alloc("s2"), Var.alloc("p2"), Var.alloc("s));
//new
ElementPathBlock epb;
int index = -1;
for(int i=0; i<oldQP.getElements().size(); i++){
if(oldQP.getElements().get(i) instanceof ElementPathBlock){
//...get last index of instanceof ElementPathBlock, if exists.
index = i;
}
}
if(index > -1){
//...found occurence of ElementPathBlock we will add to
epb = (ElementPathBlock) oldQP.getElements().get(index);
}else{
//...no occurence, so make new ElementPathBlock to add
epb = new ElementPathBlock();
}
//add Triple(s) to epb, not to oldQP
epb.addTriple(t);
//re-add (or add for first time) ElementPathBlock to the ArrayList of Elements
if(index > -1){
oldQP.getElements().set(index, epb);
}else{
oldQP.getElements().add(epb);
}
//same as before
nq.setQueryPattern(oldQP);
nq.setQuerySelectType();
nq.setQueryResultStar(false);
nq.addResultVar("s");
现在查看oldQP,经过上述操作后,我们发现格式正确,并且句点放置正确:
{?s ?p ?o.
?s2 ?p2 ?s.
}
答案 2 :(得分:0)
以下代码按照您的描述创建查询,复制,添加三重模式,打印并运行两个查询。你是对的,查询的打印形式缺少.
通常存在的地方。但是,作为RobV pointed out,打印奇怪性对查询结果没有任何影响。如果您在实际案例中得到的结果不同,您能否突出显示它与此不同的地方?
import com.hp.hpl.jena.graph.Triple;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.ResultSetFormatter;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.sparql.core.Var;
import com.hp.hpl.jena.sparql.syntax.ElementGroup;
public class AddTriplePattern {
public static void main(String[] args) {
// Create the original query
final String queryString = "" +
"select * where {\n" +
" ?s ?p ?o .\n" +
"}\n" +
"";
final Query query = QueryFactory.create( queryString );
// Create the new query and add `?s2 ?p2 ?o2`. Print the new query
// before and after adding the triple pattern. Sure enough, after
// the modification, the pattern is printed without a `.` between the
// triples. The space between the variables is also a bit bigger.
final Query newQuery = QueryFactory.create( query );
System.out.println( "== before ==\n"+newQuery );
final ElementGroup eg = (ElementGroup) newQuery.getQueryPattern();
final Triple t = new Triple( Var.alloc( "s2"), Var.alloc( "p2" ), Var.alloc( "o2" ));
eg.addTriplePattern( t );
newQuery.setQueryResultStar(false);
newQuery.addResultVar( "s2" );
System.out.println( "== after ==\n"+newQuery );
// Create a model with a single triple [a, a, a].
final Model model = ModelFactory.createDefaultModel();
final Resource a = model.createResource( "urn:ex:a" );
model.add( a, a.as( Property.class ), a );
// Run both the original query and the new query on the model. Both
// return the expected results.
ResultSetFormatter.out( QueryExecutionFactory.create( query, model ).execSelect() );
ResultSetFormatter.out( QueryExecutionFactory.create( newQuery, model ).execSelect() );
}
}
输出结果为:
== before ==
SELECT *
WHERE
{ ?s ?p ?o }
== after ==
SELECT ?s2
WHERE
{ ?s ?p ?o
?s2 ?p2 ?o2 .
}
----------------------------------------
| s | p | o |
========================================
| <urn:ex:a> | <urn:ex:a> | <urn:ex:a> |
----------------------------------------
--------------
| s2 |
==============
| <urn:ex:a> |
--------------