首次 SPARQL 查询
在本节中,我们将查看一个简单的首次查询,并演示如何使用 Jena 执行该查询。
查询的 “hello world”
文件 "q1.rq "包含以下查询:
SELECT ?x
WHERE { ?x <http://www.w3.org/2001/vcard-rdf/3.0#FN> "John Smith" }
使用命令行查询应用程序来执行该查询。
---------------------------------
| x |
=================================
| <http://somewhere/JohnSmith/> |
---------------------------------
其工作原理是将 WHERE 子句中的三元组模式与 RDF 图中的三元组进行匹配。三元组的谓词和宾语都是固定值,因此该模式只匹配具有这些值的三元组。主语是一个变量,对变量没有其他限制。该模式会匹配任何具有这些谓词和对象值的三元组,并且会匹配 x 的解。
<> 包围的内容是一个URI(统一资源标识符,也可以是IRI,国际化资源标识符),用来唯一标识一个资源,就像一个网址或标识符一样。“” 包围的内容是一个纯文本字面量,表示资源的属性或值。类似于Turtle、N3或N-triples等格式,带类型的字面量可以用 ^^ 表示,用来说明字面量的数据类型。语言标签可以通过 @ 来添加。
?x 是一个名为 x 的变量,?不构成名称的一部分,因此不会出现在表格输出中。
有一个匹配项。查询在 x 查询变量中返回匹配结果。所示输出是通过使用 ARQ 的一个命令行应用程序获得的。
执行查询
Jena 发行版 bat/ 和 bin/ 目录中有一些助手脚本。您应该在使用前检查这些脚本。它们可以放置在shell命令路径上。
Windows 设置
执行
bat\sparql.bat --data=doc\Tutorial\vc-db-1.rdf --query=doc\Tutorial\q1.rq
你可以将 bat/ 目录添加到你的 classpath 中,或者从中复制程序出来使用。
用于 Linux/Cygwin/Unix 的 bash 脚本
执行
bin/sparql --data=doc/Tutorial/vc-db-1.rdf --query=doc/Tutorial/q1.rq
直接使用 Java 命令行应用程序(这不是必须的)
您需要设置 classpath,以包含 Jena 发行版 lib/ 目录中的所有 jar 文件。
java -cp 'DIST/lib/*' arq.sparql ...
其中的 “DIST” 是指 “apache-jena-VERSION” 目录,你需要将实际的版本号替换到 “VERSION” 的位置上。也就是说,你需要根据你具体的情况,将 “DIST” 替换成你安装的 Apache Jena 版本的目录。
使用 Java 代码进行查询
下面代码里用 pr 表示前缀:<http://www.w3.org/2001/vcard-rdf/3.0#>
,可以任意命名。
import org.apache.jena.query.Query;
import org.apache.jena.query.QueryExecution;
import org.apache.jena.query.QueryExecutionFactory;
import org.apache.jena.query.QueryFactory;
import org.apache.jena.query.QuerySolution;
import org.apache.jena.query.ResultSet;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
public class Test01 {
static final String inputFileName = "java01/src/main/java/come/jena/rdf/vc-db-1.rdf";
public static void main(String[] args) {
// Load RDF data into a model
Model model = ModelFactory.createDefaultModel();
model.read(inputFileName); // Load your RDF data file
// Define a SPARQL query
String queryString =
"PREFIX pr:<http://www.w3.org/2001/vcard-rdf/3.0#>" +
" SELECT ?x WHERE { ?x pr:FN \"John Smith\" }";
/*String queryString = "SELECT ?subject " +
"WHERE { ?subject <http://www.w3.org/2001/vcard-rdf/3.0#FN> \"John Smith\" }";*/
Query query = QueryFactory.create(queryString);
// Execute the query
try (QueryExecution qexec = QueryExecutionFactory.create(query, model)) {
ResultSet results = qexec.execSelect();
// Process the query results
while (results.hasNext()) {
QuerySolution soln = results.nextSolution();
System.out.println(soln);
System.out.println("x: " + soln.get("x"));
//System.out.println("Subject: " + soln.get("subject"));
//System.out.println("Predicate: " + soln.get("predicate"));
//System.out.println("Object: " + soln.get("object"));
}
}
catch (Exception e){
e.printStackTrace();
}
}
}
因为查询的变量是x,所有在输出结果时要执行 soln.get("x")
语句,如果查询的变量为 y,则输出时要执行 soln.get("y")
。
在Java中,当你从查询结果中使用 soln.get(“?x”) 或 soln.get(“x”) 时,?x 和 x 是等价的。Java中的SPARQL查询结果处理库通常允许你使用带有或不带有 ? 前缀的变量名,以获得相同的结果。
运行结果:
Jena 官方文档:https://jena.apache.org/tutorials/sparql_query1.html