Java 如何使用jena querybuilder构建SPARQL列表输入?

Java 如何使用jena querybuilder构建SPARQL列表输入?,java,sparql,jena,apache-jena,jena-querybuilder,Java,Sparql,Jena,Apache Jena,Jena Querybuilder,我有一堆代码使用ApacheJena QueryBuilderAPI(SelectBuilderclass)。我正在尝试向现有SPARQL查询中添加这样的术语: (?a ?b ?c) :hasMagicProperty ?this . 我已经验证了这个查询在TopBraid中是有效的,但是我不知道如何在Jena API中表示(?a,?b,?c)。要将此变量列表转换为有效的Jena资源节点,我必须做什么 如果SPARQL构建框架对类型化文本、IRIs和过滤器以及这个列表构造有强大

我有一堆代码使用ApacheJena QueryBuilderAPI(
SelectBuilder
class)。我正在尝试向现有SPARQL查询中添加这样的术语:

        (?a ?b ?c) :hasMagicProperty ?this .
我已经验证了这个查询在TopBraid中是有效的,但是我不知道如何在Jena API中表示
(?a,?b,?c)
。要将此变量列表转换为有效的Jena资源节点,我必须做什么

如果SPARQL构建框架对类型化文本、IRIs和过滤器以及这个列表构造有强大的支持,我愿意探索其他SPARQL构建框架。我浏览了其他几个用于构建SPARQL查询的框架,但它们似乎都没有列表结构

编辑

我的查询构建代码(在Groovy中)如下所示:

def selectBuilder = new SelectBuilder()
selectBuilder.addPrefixes(...)
def thisVar = Var.alloc('this')
selectBuilder.addOptional(thisVar, 'rdf:type', ':MyEntity')

def aVar = Var.alloc('a')
def bVar = Var.alloc('b')
def cVar = Var.alloc('c')
List<Var> abc = [aVar, bVar, cVar]
//this doesn't work!!!
selectBuilder.addWhere(abc, ':hasMagicProperty', thisVar)
selectBuilder.addWhere(aVar, ':hasACode', 'code A')
selectBuilder.addWhere(bVar, ':hasBCode', 'code B')
selectBuilder.addWhere(cVar, ':hasCCode', 'code C')

def sparqlQuery = selectBuilder.buildString()
_:b0      rdf:first             ?c ;
          rdf:rest              rdf:nil .
_:b1      rdf:first             ?b ;
          rdf:rest              _:b0 .
_:b2      rdf:first             ?a ;
          rdf:rest              _:b1 ;
          :hasMagicProperty  ?this .

我编写了queryBuilder,我认为在它的当前状态下,它不会做你想做的事情。查询生成器基于(但尚未完全实现)w3c SPARQL 1.1建议:

但是,我认为您可以使用Jena QueryFactory创建查询

String queryString = "SELECT * WHERE {  "+
  " OPTIONAL { ?this a :MyEntity } ."+
  " (?a ?b ?c) :hasMagicProperty ?result . "+
  " ?a :hasACode 'code A' . "+
  " ?b :hasACode 'code B' . "+
  " ?c :hasACode 'code C' ."+
  " }";
Query query = QueryFactory.create(queryString) ;
不幸的是,我认为这不是你真正想要的。请注意,这不会绑定到任何其他语句,因此将生成所有
:MyEntity
类型主题与
?a
?b
?c
和`?result``绑定的叉积

如果您可以使用QueryFactory创建查询,我可以确保QueryBuilder将支持它

更新 我已经更新了QueryBuilder(下一个快照应该包含这些更改)。您现在应该能够执行以下操作:

Var aVar = Var.alloc('a')
Var bVar = Var.alloc('b')
Var cVar = Var.alloc('c')
selectBuilder.addWhere(selectBuilder.list(aVar, bVar, cVar),  ':hasMagicProperty', thisVar)
selectBuilder.addWhere(aVar, ':hasACode', 'code A')
selectBuilder.addWhere(bVar, ':hasBCode', 'code B')
selectBuilder.addWhere(cVar, ':hasCCode', 'code C')
如果您还可以简单地在列表参数中添加值的标准文本版本,如:

selectBuilder.list( "<a>", "?b", "'c'" )
selectBuilder.list(“,”b“,”c“)

以下方法是一种变通方法,使用多个三元组递归构建RDF列表:

/*
 * Jena querybuilder does not yet support RDF lists. See:
 * http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#collections
 */
private Node buildRdfCollection(SelectBuilder queryBuilder, List<?> itemList) {
    if (itemList.isEmpty()) {
        return RDF.nil.asNode()
    }

    def head = itemList.first()
    def rest = buildRdfCollection(queryBuilder, itemList.subList(1, itemList.size()))

    def listNode = NodeFactory.createAnon()
    queryBuilder.addWhere(listNode, RDF.first, head)
    queryBuilder.addWhere(listNode, RDF.rest, rest)
    return listNode
}

...

def listNode = buildRdfCollection(queryBuilder, abc)
queryBuilder.addWhere(listNode, ':hasMagicProperty', thisVar)
这是一个长篇大论,相当于:

(?a ?b ?c) :hasMagicProperty ?this .

我认为您需要使用RDFList@谢谢你的回复。我花了一些时间研究rdflistapi,但我不知道如何使用jenavars构建一个rdflistapi。您能提供一个代码示例吗?谢谢!那太棒了!我将为您提供更完整的示例查询。以下是SPARQL 1.1规范的相关部分:将第一个示例查询片段中的“?result”更改为“?this”,因此我的尝试更有意义。
(?a ?b ?c) :hasMagicProperty ?this .