0

我正在尝试从 Java 中的资源中获取 URI,但它始终是null. 现在,我正在尝试这个:

for ( ; rs.hasNext() ; ) {
  QuerySolution qs  = rs.next();
  System.out.println( qs.getLiteral("label"));
  System.out.println( qs.getResource("label"));
  …

文字返回得很好,我什至尝试了资源“?film”,但资源仍然为空。这是我的 SPARQL 查询:

PREFIX mdb: <http://data.linkedmdb.org/resource/movie/film>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> 
select ?label ?film where {
  ?film mdb:id ?uri .
  ?film rdfs:label ?label . 
  filter regex(?label,  + queryVar +
}

queryVar只是用户输入,例如“蝙蝠侠”。

编辑:我的查询中有一个错字:这是我的查询:

String sparqlQuery = "PREFIX mdb: http://data.linkedmdb.org/resource/movie/film " + "PREFIX rdfs: http://www.w3.org/2000/01/rdf-schema# " + "select ?label ?film" + "where" + "{ ?film mdb:id ?uri ." + "?film rdfs:label ?label ." + " }" + "";

仔细观察 ?film 和 where,它们变成了 filmwhere,这就是问题所在。

感谢Joshua,我明白了。

4

1 回答 1

2

文档QuerySolution#getResource说_

Resource getResource(String varName)

返回此绑定中命名变量的值,转换为资源。返回 null 表示此解决方案中不存在该变量。异常表明它存在但不是资源。

如果您得到null,则查询解决方案中不存在某些值。但是,如果没有看到您的实际查询,就无法判断您是否由于某种原因(例如,queryVar不是您认为的那样)得到空结果。如果queryVar只是一个没有引号的字符串,你最终会得到一个像这样的查询

filter regex(?label,Batman)

代替

filter regex(?label,"Batman")

无论如何,我将您的查询修改为我们可以使用 Jena 的命令行工具运行的查询:

PREFIX mdb: <http://data.linkedmdb.org/resource/movie/film>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> 
select ?label ?film
where {
  service <http://data.linkedmdb.org/sparql> {
    ?film mdb:id ?uri .
    ?film rdfs:label ?label . 
    filter regex(?label, "Batman")
  }
}

当我运行它时,我得到如下结果:

$ arq --query query.sparql --data data.n3 
-----------------------------------------------------------------------------------------
| label                                | film                                           |
=========================================================================================
| "Batman"                             | <http://data.linkedmdb.org/resource/film/2>    |
| "Batman"                             | <http://data.linkedmdb.org/resource/film/3>    |
| "Batman & Robin"                     | <http://data.linkedmdb.org/resource/film/4>    |
| "Batman: Mask of the Phantasm"       | <http://data.linkedmdb.org/resource/film/737>  |
| "Batman: Mystery of the Batwoman"    | <http://data.linkedmdb.org/resource/film/974>  |
| "Batman Beyond: Return of the Joker" | <http://data.linkedmdb.org/resource/film/1802> |
| "Batman & Mr. Freeze: SubZero"       | <http://data.linkedmdb.org/resource/film/2124> |
-----------------------------------------------------------------------------------------

label并且film总是被束缚在其中。所有的标签都是文字,所以你应该能够做到

qs.getLiteral("label")

并得到一个字面量。这听起来更像是你想要film变量的 URI,你会用

qs.getResource("film").getURI()

当然,toString()如果您想要 URI 字符串,您可以在之后使用。

顺便说一句,而不是做

"filter(?label, " + queryVar + "…"

您可能需要考虑使用ParameterizedSparqlString来安全地替换 queryVar。否则,会发生queryVar类似

"\"Batman\") UNION { ?film hasPassword ?label }"

它被替换了吗?你突然泄露了一堆信息。即使没有敏感信息泄露,您最终仍可能在 SPARQL 端点上造成巨大负载,从而有效地发起拒绝服务攻击。

于 2013-09-10T15:46:08.723 回答