【问题标题】:SPARQL parser for Java CodeJava 代码的 SPARQL 解析器
【发布时间】:2013-01-24 11:44:57
【问题描述】:

是否有任何简单的方法可以在 java 的变量中解析 sparql 查询,例如 python 中的 Fyzz?如何使用 Jena 或 sesame API?

【问题讨论】:

    标签: java sparql


    【解决方案1】:

    您可以使用 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
    

    (见the Query java documentation

    尝试从教程'Manipulating SPARQL using ARQ' 开始。这将使您了解查询是如何表示的,以及如何从中提取内容(visitors 特别有用)。虽然最初语法级别是最熟悉的,但对于许多任务,algebra 效果更好,因为它对应于查询实际执行的操作。

    【讨论】:

    • 我用 String sparql = "SELECT ?a ?b ?c WHERE { ?a ?b . ?a ?c . }";查询查询 = QueryFactory.create(sparql);但我在线程“main”java.lang.NoClassDefFoundError: com/hp/hpl/jena/shared/PrefixMapping$IllegalPrefixException 在 com.hp.hpl.jena.query.QueryFactory.create(QueryFactory.java:68 ) 在 com.hp.hpl.jena.query.QueryFactory.create(QueryFactory.java:40) 在 com.hp.hpl.jena.query.QueryFactory.create(QueryFactory.java:28) 在 testsparql.main(testsparql. java:13)
    • 您的类路径中需要 jena-arq 和 jena-core 库。我怀疑你错过了后者。
    • 哦,还有 jena-iri iirc。 (如果可能,使用依赖管理器)
    • 我使用 eclipse...我使用了这些外部 jar,但我仍然在 com.hp.hpl.jena.query.ARQ 处收到错误 ava.lang.NoClassDefFoundError: org/slf4j/LoggerFactory。(ARQ.java:53).(Query.java:63) com.hp.hpl.jena.query.QueryFactory.create(QueryFactory.java :78) 在 com.hp.hpl.jena.query.QueryFactory.create(QueryFactory.java:52) 在 com.hp.hpl.jena.query.QueryFactory.create(QueryFactory.java:40) 在 testsparql.main( testsparql.java:14) 引起:java.lang.ClassNotFoundException: org.slf4j.LoggerFactory
    • 我强烈建议花一些时间学习如何正确设置 Eclipse 项目以及 Java CLASSPATH 的概念。我的建议是不要手动管理依赖项(因为很容易出错)。周围有很多很好的示例可供您学习并帮助您快速入门。
    【解决方案2】:

    以下是使用 Sesame 解析和操作 SPARQL 查询的方法:

    解析:

    ParsedQuery pq = QueryParserUtil.parseQuery(QueryLanguage.SPARQL, queryString);
    

    它的输出是ParsedQuery,它是查询的代数对象表示。如果您希望专门获取解析树本身,这也是可能的:

    ASTQueryContainer parseTree = SyntaxTreeBuilder.parseQuery(queryString);
    

    然后,您可以通过实现自定义 SyntaxTreeBuilderVisitor 直接操作此抽象语法树(提示:扩展 ASTVisitorBase,因此您只需覆盖您真正想要做某事的方法)。

    如果我们回到代数模型,您可以在芝麻帆存储库上执行ParsedQuery

    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();
    }
    

    【讨论】:

      猜你喜欢
      • 2012-01-30
      • 1970-01-01
      • 1970-01-01
      • 2011-07-26
      • 2011-10-23
      • 2015-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多