1

特定のクエリに基づいて新しいクエリを作成しようとしています (古いクエリ - これは変更できません)。

単純で有効な 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 ではないためです。では、この問題を回避するにはどうすればよいでしょうか。すべてのトリプルに終了期間がある場合、この問題は発生しませんが、これを機能させる方法が見つからないようです。

ありがとう!

4

3 に答える 3

1

ここであなたの質問に完全に従っているかどうかはわかりません

2 番目のクエリはどこから来たのですか? toString()新しいクエリ オブジェクトを呼び出していますか?この場合、これはクエリを印刷するための内部ロジックのバグである可能性があります。

また、使用している ARQ のバージョンは何ですか?

于 2013-03-22T18:35:13.107 に答える
1

そのため、回避策/解決策を見つけたようです。ElementGroup行によって作成されたオブジェクトをデバッグして詳しく調べた後

ElementGroup oldQP = (ElementGroup)q.getQueryPattern();

Element オブジェクトの ArrayList をサポートしていることに気付きました (メソッドで取得ElementGroup.getElements())。(メソッドを介して) トリプルを追加しようとする前に、このリストにElementGroup.addTriplePattern(...)あったのは Type のオブジェクトだけでしたElementPathBlock。わかりました。

次に、次のように、上記の方法でトリプルを追加しようとします。

Triple t = Triple.create(...);
oldQP.addTriplePattern(t);

ElementTriplesBlockこれにより、ElementGroup の要素のリストに新しい要素が追加されることに気付きました。これが犯人のようです。したがって、私の解決策は、代わりに の最後の出現を取得しElementPathBlock、トリプルを ElementGroup に追加するのではなく、そのオブジェクトに追加することでした (したがって、新しいElementTriplesBlockを ArrayList に追加することを回避します)。

//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.
}
于 2013-03-25T14:22:28.420 に答える