PythonのFyzzのように、Javaの変数でsparqlクエリを解析する簡単な方法はありますか? Jena または sesame API はどのように使用できますか?
2 に答える
Apache Jena のARQを使用して、Java で SPARQL を構文解析または代数レベルで非常に簡単に解析および操作できます。QueryFactory.create(queryString)
クエリの Java 表現を提供します。次に、ぶらぶらしてください:
Query query = QueryFactory.create(queryString);
query.isSelectType() && query.isQueryResultStar(); // of the form SELECT *?
query.getDatasetDescription(); // FROM / FROM NAMED bits
query.getQueryPattern(); // The meat of the query, the WHERE bit
...etc etc..
Op op = Algebra.compile(query); // Get the algebra for the query
( Query Java のドキュメントを参照してください)
チュートリアル「ARQ を使用した SPARQL の操作」から始めてみてください。これにより、クエリがどのように表現されるか、およびそれらから物事を引き出す方法についての感触が得られます (visitors
特に便利です)。最初は構文レベルが最もよく知られていますが、多くのタスクでは、クエリが実際に行うことに対応しているため、代数の方がうまく機能します。
Sesameを使用してSPARQLクエリを解析および操作する方法は次のとおりです。
パースします:
ParsedQuery pq = QueryParserUtil.parseQuery(QueryLanguage.SPARQL, queryString);
これの出力はParsedQuery
、クエリの代数オブジェクト表現であるです。解析ツリー自体を具体的に取得したい場合は、それも可能です。
ASTQueryContainer parseTree = SyntaxTreeBuilder.parseQuery(queryString);
次に、カスタムSyntaxTreeBuilderVisitorを実装することにより、この抽象構文ツリーを直接操作できます(ヒント:ASTVisitorBase
実際に何かを実行したい場所でのみメソッドをオーバーライドする必要があるように拡張します)。
代数モデルに戻ると、ParsedQuery
SesameSailリポジトリでを実行できます。
if (pq instanceof ParsedTupleQuery) {
SailTupleQuery query = new SailTupleQuery(pq, repositoryConnection);
TupleQueryResult result = query.evaluate();
} else if (pq instanceof ParsedGraphQuery) {
// etc for other query types
}
ParsedQuery
実行する前に操作するには、 QueryModelVisitor実装を使用します。たとえば、独自のカスタムクエリマニピュレータを使用します。
QueryModelVisitor myVisitor = new MyCustomQueryModelVisitor();
pq.getTupleExpr().visit(myVisitor);
このようなカスタムクエリモデルの訪問者を使用すると、クエリを完全に制御したり、クエリを最適化したり、実際に別の構文に書き換えたりすることができます。
この操作を抽象構文木(AST)のレベルで行うか、クエリモデルのレベルで行うかは、好みの問題です。クエリモデルは、クエリの計画/最適化および部分的な書き換え(後で使用するため)に関してより柔軟性があります。 Sesameストアでの実行)、別の目的でクエリを完全に書き直すことが目的の場合(たとえば、Sesame以外のストアで実行する場合)、構文ツリーを直接操作する方が簡単な場合があります。
余談ですが、クエリを解析して実行する上記の方法は、物事を行うための回り道です。解析されたクエリを実行する前に操作する必要がない場合は、次のようにリポジトリでクエリを準備して実行するだけです。
String queryString = "SELECT ...";
RepositoryConnection conn = repo.getConnection();
try {
TupleQuery tq = conn.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
TupleQueryResult result = tq.evaluate();
}
finally {
conn.close();
}