2013-03-04 53 views
8

假設我有一些耶拿查詢對象:如何獲取耶拿查詢的所有主題?

String query = "SELECT * WHERE{ ?s <some_uri> ?o ...etc. }"; 
Query q = QueryFactory.create(query, Syntax.syntaxARQ); 

什麼是讓所有在查詢中三元的主題的最佳方式?優選地,不需要手動進行任何字符串解析/操作。

例如,給定一個查詢

SELECT * WHERE { 
    ?s ?p ?o; 
     ?p2 ?o2. 
    ?s2 ?p3 ?o3. 
    ?s3 ?p4 ?o4. 
    <http://example.com> ?p5 ?o5. 
} 

我希望已經恢復了一些列表,它看起來像

[?s, ?s2, ?s3, <http://example.com>] 

換句話說,我想在一個查詢中的所有對象的列表。即使只有那些變量或文字/ uris的主題將是有用的,但我想查找查詢中所有主題的列表。

我知道有方法返回結果變量(Query.getResultVars)和一些其他信息(見http://jena.apache.org/documentation/javadoc/arq/com/hp/hpl/jena/query/Query.html),但我似乎無法找到任何具體的查詢主題(所有結果的列表變量也會返回謂詞和對象)。

任何幫助表示讚賞。

+0

查詢字符串是給定的還是可以改變的?因爲通過更改查詢可以很容易地解決您的問題。 – Sentry 2013-03-04 14:59:16

+0

我想我終於明白你的意思了。你不需要結果中的所有主題,但是查詢中主題的所有綁定變量,對不對?如果是這樣,請在問題中更明顯。 – Sentry 2013-03-04 15:09:49

+0

爲什麼不對結果變量進行評估?你想創建一個結果變量表嗎?如果不是,請舉個例子。 – 2013-03-04 15:13:05

回答

9

有趣的問題。你需要做的是通過查詢,併爲每個三元組遍歷並查看第一部分。

最健壯的方法是通過元素步行者來完成查詢的每個部分。在您的案例中,它可能看起來非常優秀,但查詢可以包含各種各樣的內容,包括FILTERsOPTIONALs和嵌套SELECTs。使用助行器意味着你可以忽略那些東西,只關注你想要的東西:

Query q = QueryFactory.create(query); // SPARQL 1.1 

// Remember distinct subjects in this 
final Set<Node> subjects = new HashSet<Node>(); 

// This will walk through all parts of the query 
ElementWalker.walk(q.getQueryPattern(), 
    // For each element... 
    new ElementVisitorBase() { 
     // ...when it's a block of triples... 
     public void visit(ElementPathBlock el) { 
      // ...go through all the triples... 
      Iterator<TriplePath> triples = el.patternElts(); 
      while (triples.hasNext()) { 
       // ...and grab the subject 
       subjects.add(triples.next().getSubject()); 
      } 
     } 
    } 
); 
+0

所以,這很有道理,謝謝你指出'ElementWalker'和'ElementVisitor's。但是,這個實現似乎不適用於上述查詢(或其他任何)。我發現很難調試這種訪問方法的壓倒一切;任何想法可能是什麼問題? 任何時候我嘗試這種重寫,我只是得到一個空的列表返回。任何人都有另一個這樣的例子嗎? – 2013-03-04 19:56:39

+2

您需要查看ElementPathBlock中的SPARQL 1.1以及ElementTriplesBlock。看到PatternVarsVisitor – AndyS 2013-03-04 22:03:31

+0

啊,當然。上面的修正版本適用於我。 – user205512 2013-03-05 00:12:03