参数化SPARQL查询 [英] parameterized SPARQL Query
问题描述
我想用Java Jena编写一个参数化的SPARQL查询,在其中注入查询中的三元组之一
所以在下面的代码中,我需要将值作为字符串注入传递给类的
但是,SPARQL查询是正确的,因此当我用类名替换"value"时,我得到了正确的结果
我尝试了两个都不起作用的代码,没有结果或运行时错误
第一个代码:
package ontology;
import org.apache.jena.iri.impl.Main;
import com.hp.hpl.jena.query.ParameterizedSparqlString;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.util.FileManager;
public class SPARQL {
public static void sparqlTest( String str)
{
FileManager.get().addLocatorClassLoader(Main.class.getClassLoader());
Model model=FileManager.get().loadModel("ASO.owl");
String queryString=
"PREFIX rdfs:<http://www.w3.org/2000/01/rdf-schema#>"+
"PREFIX rdf:< http://www.w3.org/1999/02/22-rdf-syntax-ns#>"+
"PREFIX HASO:< http://www.semanticweb.org/rabaa006/ontologies/2014/4/HASO#>"+
"SELECT ?x "+
"WHERE"+
" {?x rdfs:subClassOf HASO:Affective_State}";
ParameterizedSparqlString queryStr = new ParameterizedSparqlString(queryString);
queryStr.setLiteral("value", str);
Query query=QueryFactory.create(queryStr.toString());
QueryExecution qexec = QueryExecutionFactory.create(query,model);
try {
ResultSet results = qexec.execSelect();
while ( results.hasNext()){
QuerySolution soln = results.nextSolution();
String strg=soln.getResource("?x").toString();
//System.out.println(strg);
String number = strg.substring(strg.lastIndexOf("#") + 1);
System.out.println(number);
}}
finally{
qexec.close();}
}
}
第二个代码:
package ontology;
import org.apache.jena.iri.impl.Main;
import com.hp.hpl.jena.query.ParameterizedSparqlString;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.util.FileManager;
public class SPARQL {
public static void sparqlTest( String str)
{
FileManager.get().addLocatorClassLoader(Main.class.getClassLoader());
Model model=FileManager.get().loadModel("ASO.owl");
ParameterizedSparqlString pss = new ParameterizedSparqlString();
pss.setCommandText (
"PREFIX rdfs:<http://www.w3.org/2000/01/rdf-schema#>"+
"PREFIX rdf:< http://www.w3.org/1999/02/22-rdf-syntax-ns#>"+
"PREFIX HASO:< http://www.semanticweb.org/rabaa006/ontologies/2014/4/HASO#>"+
"SELECT ?x "+
"WHERE"+
" {?x rdfs:subClassOf HASO:valuee}");
pss.setLiteral("value", str);
Query query=QueryFactory.create(pss.toString());
QueryExecution qexec = QueryExecutionFactory.create(query,model);
try {
ResultSet results = qexec.execSelect();
while ( results.hasNext()){
QuerySolution soln = results.nextSolution();
String strg=soln.getResource("?x").toString();
//System.out.println(strg);
String number = strg.substring(strg.lastIndexOf("#") + 1);
System.out.println(number);
}}
finally{
qexec.close();}
}
}
使用setLitral()的问题是将String注入到由双引号包围的查询中,例如:
String queryString
= "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n"
+ "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n"
+ "PREFIX HASO: <http://www.semanticweb.org/rabaa006/ontologies/2014/4/HASO#>"
+ "SELECT ?x WHERE {\n"
+ " ?x rdfs:subClassOf ?clazz \n"
+ "}\n";
ParameterizedSparqlString queryStr = new ParameterizedSparqlString(queryString);
queryStr.setLiteral("clazz", "HASO:Affective_State");
System.out.println(queryStr.toString());
查询的结果将类似于:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX HASO: <http://www.semanticweb.org/rabaa006/ontologies/2014/4/HASO#>SELECT ?x WHERE {
?x rdfs:subClassOf "HASO:Affective_State"
}
如您在上方看到的吗?x rdfs:subClassOf"HASO:Affective_State"其中"HASO:Affective_State" .错误的类名,因为它包含",因此如果执行该查询,将不会返回任何结果. 解决方案 使用String.format而不是ParameterizedSparqlString :: setLiteral:
String q
= "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n"
+ "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n"
+ "PREFIX HASO: <http://www.semanticweb.org/rabaa006/ontologies/2014/4/HASO#>"
+ "SELECT ?x WHERE {\n"
+ " ?x rdfs:subClassOf %s \n"
+ "}\n"
+ "LIMIT %d";
q = String.format(q, "HASO:Affective_State", 2);
System.out.println(q);
结果:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX HASO: <http://www.semanticweb.org/rabaa006/ontologies/2014/4/HASO#>SELECT ?x WHERE {
?x rdfs:subClassOf HASO:Affective_State
}
LIMIT 2
正如您在上面看到的,HASO:Affective_State和2已正确注入,因此您可以使用String.format [%s表示字符串,%d表示数字,等等.] 注入任意数量的参数. >
完整示例:
public static void main(String[] args) {
JenaSystem.init();
UpdateFactory.create();
Model model = FileManager.get().loadModel("ASO.owl");
String q
= "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n"
+ "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n"
+ "PREFIX HASO: <http://www.semanticweb.org/rabaa006/ontologies/2014/4/HASO#>"
+ "SELECT ?x WHERE {\n"
+ " ?x rdfs:subClassOf %s \n"
+ "}\n"
+ "LIMIT %d";
q = String.format(q, "HASO:Affective_State", 2);
System.out.println(q);
Query query = QueryFactory.create(q);
QueryExecution qexec = QueryExecutionFactory.create(query, model);
ResultSet resSet = qexec.execSelect();
while (resSet.hasNext()) {
QuerySolution soln = resSet.nextSolution();
String strg = soln.getResource("?x").toString();
System.out.println(">>>>>>> " + strg);
String number = strg.substring(strg.lastIndexOf("#") + 1);
System.out.println("<<<<<< " + number);
}
}
I want to code a parameterized SPARQL Query in Java Jena where one of the triple in query be injected
so in the code below I need to inject value as a string the pass to the class
However, the SPARQL query is correct so when I replace "value" with the class name I got the right result
I tried two code non of them worked No result or run time error
the first code:
package ontology;
import org.apache.jena.iri.impl.Main;
import com.hp.hpl.jena.query.ParameterizedSparqlString;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.util.FileManager;
public class SPARQL {
public static void sparqlTest( String str)
{
FileManager.get().addLocatorClassLoader(Main.class.getClassLoader());
Model model=FileManager.get().loadModel("ASO.owl");
String queryString=
"PREFIX rdfs:<http://www.w3.org/2000/01/rdf-schema#>"+
"PREFIX rdf:< http://www.w3.org/1999/02/22-rdf-syntax-ns#>"+
"PREFIX HASO:< http://www.semanticweb.org/rabaa006/ontologies/2014/4/HASO#>"+
"SELECT ?x "+
"WHERE"+
" {?x rdfs:subClassOf HASO:Affective_State}";
ParameterizedSparqlString queryStr = new ParameterizedSparqlString(queryString);
queryStr.setLiteral("value", str);
Query query=QueryFactory.create(queryStr.toString());
QueryExecution qexec = QueryExecutionFactory.create(query,model);
try {
ResultSet results = qexec.execSelect();
while ( results.hasNext()){
QuerySolution soln = results.nextSolution();
String strg=soln.getResource("?x").toString();
//System.out.println(strg);
String number = strg.substring(strg.lastIndexOf("#") + 1);
System.out.println(number);
}}
finally{
qexec.close();}
}
}
The Second code:
package ontology;
import org.apache.jena.iri.impl.Main;
import com.hp.hpl.jena.query.ParameterizedSparqlString;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.util.FileManager;
public class SPARQL {
public static void sparqlTest( String str)
{
FileManager.get().addLocatorClassLoader(Main.class.getClassLoader());
Model model=FileManager.get().loadModel("ASO.owl");
ParameterizedSparqlString pss = new ParameterizedSparqlString();
pss.setCommandText (
"PREFIX rdfs:<http://www.w3.org/2000/01/rdf-schema#>"+
"PREFIX rdf:< http://www.w3.org/1999/02/22-rdf-syntax-ns#>"+
"PREFIX HASO:< http://www.semanticweb.org/rabaa006/ontologies/2014/4/HASO#>"+
"SELECT ?x "+
"WHERE"+
" {?x rdfs:subClassOf HASO:valuee}");
pss.setLiteral("value", str);
Query query=QueryFactory.create(pss.toString());
QueryExecution qexec = QueryExecutionFactory.create(query,model);
try {
ResultSet results = qexec.execSelect();
while ( results.hasNext()){
QuerySolution soln = results.nextSolution();
String strg=soln.getResource("?x").toString();
//System.out.println(strg);
String number = strg.substring(strg.lastIndexOf("#") + 1);
System.out.println(number);
}}
finally{
qexec.close();}
}
}
The problem with using setLitral() is injecting String into query bounded by double quotes like:
String queryString
= "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n"
+ "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n"
+ "PREFIX HASO: <http://www.semanticweb.org/rabaa006/ontologies/2014/4/HASO#>"
+ "SELECT ?x WHERE {\n"
+ " ?x rdfs:subClassOf ?clazz \n"
+ "}\n";
ParameterizedSparqlString queryStr = new ParameterizedSparqlString(queryString);
queryStr.setLiteral("clazz", "HASO:Affective_State");
System.out.println(queryStr.toString());
The result of Query will be like:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX HASO: <http://www.semanticweb.org/rabaa006/ontologies/2014/4/HASO#>SELECT ?x WHERE {
?x rdfs:subClassOf "HASO:Affective_State"
}
As you see above ?x rdfs:subClassOf "HASO:Affective_State" where "HASO:Affective_State" . is wrong class name because it contains "" so no results will return if you execute that query. The SOLUTION Use String.format instead of ParameterizedSparqlString:: setLiteral:
String q
= "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n"
+ "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n"
+ "PREFIX HASO: <http://www.semanticweb.org/rabaa006/ontologies/2014/4/HASO#>"
+ "SELECT ?x WHERE {\n"
+ " ?x rdfs:subClassOf %s \n"
+ "}\n"
+ "LIMIT %d";
q = String.format(q, "HASO:Affective_State", 2);
System.out.println(q);
The Result :
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX HASO: <http://www.semanticweb.org/rabaa006/ontologies/2014/4/HASO#>SELECT ?x WHERE {
?x rdfs:subClassOf HASO:Affective_State
}
LIMIT 2
As you see above HASO:Affective_State and 2 have been injected correctly, so you can inject as many params as you like using String.format [%s for string, %d for digit, and so on..]
Full Example:
public static void main(String[] args) {
JenaSystem.init();
UpdateFactory.create();
Model model = FileManager.get().loadModel("ASO.owl");
String q
= "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n"
+ "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n"
+ "PREFIX HASO: <http://www.semanticweb.org/rabaa006/ontologies/2014/4/HASO#>"
+ "SELECT ?x WHERE {\n"
+ " ?x rdfs:subClassOf %s \n"
+ "}\n"
+ "LIMIT %d";
q = String.format(q, "HASO:Affective_State", 2);
System.out.println(q);
Query query = QueryFactory.create(q);
QueryExecution qexec = QueryExecutionFactory.create(query, model);
ResultSet resSet = qexec.execSelect();
while (resSet.hasNext()) {
QuerySolution soln = resSet.nextSolution();
String strg = soln.getResource("?x").toString();
System.out.println(">>>>>>> " + strg);
String number = strg.substring(strg.lastIndexOf("#") + 1);
System.out.println("<<<<<< " + number);
}
}
这篇关于参数化SPARQL查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!