假设我有一些jena查询对象:
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),但我似乎无法找到任何具体的方法来获取query(所有结果变量的列表也会返回谓词和对象)。
任何帮助表示感谢。
答案 0 :(得分:9)
有趣的问题。你需要做的是完成查询,并为每个三元组迭代并查看第一部分。
最强大的方法是通过元素walker来完成查询的每个部分。在您的案例中,它可能看起来过于顶部,但查询可以包含各种内容,包括FILTERs
,OPTIONALs
和嵌套SELECTs
。使用walker意味着你可以忽略这些东西,只关注你想要的东西:
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());
}
}
}
);
答案 1 :(得分:1)
可能为时已晚,但是另一种方法是利用Jena ARQ库并创建给定查询的代数。一旦创建了代数,就可以对其进行编译,并且可以遍历所有三元组(在where子句中给出)。这是代码,希望对您有所帮助:
Query query = qExec.getQuery(); //qExec is an object of QueryExecutionFactory
// Generate algebra of the query
Op op = Algebra.compile(query);
CustomOpVisitorBase opVisitorBase = new CustomOpVisitorBase();
opVisitorBase.opVisitorWalker(op);
List<Triple> queryTriples = opVisitorBase.triples;
CustomOpVisitor类如下:
public class CustomOpVisitorBase extends OpVisitorBase {
List<Triple> triples = null;
void opVisitorWalker(Op op) {
OpWalker.walk(op, this);
}
@Override
public void visit(final OpBGP opBGP) {
triples = opBGP.getPattern().getList();
}
}
遍历三元组列表,并使用给定的属性函数,例如Triple.getSubject()等。