Jena:以编程方式构建查询时的属性路径

时间:2014-11-05 19:54:01

标签: java rdf sparql jena

我正在尝试使用Jena提供的API以编程方式构建SPARQL查询。 为了简单起见,我想要像:

SELECT *
WHERE {
  ?typ rdfs:subClassOf+ myns:SomeType .
}

问题是 rdfs:subClassOf + ,它使用属性路径。我尝试构建这样的查询:

    query = new Query();
    query.setQuerySelectType();
    query.addResultVar("typ");
    ElementTriplesBlock triplePattern = new ElementTriplesBlock();
    Node typ = NodeFactory.createVariable("typ");
    Node sometype = ...; // Assume OK

    triplePattern.addTriple(new Triple(typ, 
            ResourceFactory.createProperty(RDFS.subClassOf.getURI() + "+").asNode(),
            sometype));
    query.setQueryPattern(triplePattern);

如果我没有属性路径,即在SPARQL中只说 rdfs:subClassOf ,我可以选择:

    triplePattern.addTriple(new Triple(typ, 
            RDFS.subClassOf.asNode(),
            sometype));

哪个有效。但是我不能在URI中指定路径修饰符来构建属性,因为我得到了:

Caused by: com.hp.hpl.jena.shared.InvalidPropertyURIException: http://www.w3.org/2000/01/rdf-schema#subClassOf+
  at com.hp.hpl.jena.rdf.model.impl.PropertyImpl.checkLocalName(PropertyImpl.java:67)
  at com.hp.hpl.jena.rdf.model.impl.PropertyImpl.<init>(PropertyImpl.java:56)
  at com.hp.hpl.jena.rdf.model.ResourceFactory$Impl.createProperty(ResourceFactory.java:296)
  at com.hp.hpl.jena.rdf.model.ResourceFactory.createProperty(ResourceFactory.java:144)
  ... (test class)

所以问题是,如何通过Java API在Jena中指定这样的查询。我知道我可以使用属性路径语法从字符串中查询,但不能以编程方式构建查询。

1 个答案:

答案 0 :(得分:4)

我想我经过修补后发现了它。

首先,如果WHERE {...}部分将使用任何路径,则必须使用ElementPathBlock,因为尝试向ElementTripleBlock添加路径将引发异常。然后,不添加Triple,而是添加TriplePath。代码:

    ElementPathBlock triplePattern = new ElementPathBlock();
    Node typ = NodeFactory.createVariable("typ");
    Node sometype = ...; // Assume OK
    // This represents rdfs:subClassOf+
    Path pathSubClassOfPlus = PathFactory.pathOneOrMore1(
        PathFactory.pathLink(RDFS.subClassOf.asNode())
    );
    // This represents the SPARQL: ?typ rdfs:subClassOf+ sometype .
    TriplePath subClassOfPlus = new TriplePath(typ, pathSubClassOfPlus, sometype)
    triplePattern.addTriplePath(subClassOfPlus);
    // ... One can also add regular Triple instances afterwards
    query.setQueryPattern(triplePattern);