问题
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();}
}
}
回答1:
It's been a while since I didn't use SPARQL, but I don't see how you are actually injecting value parameter in your code. It should be something like this:
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 HASO:value ?value}");
pss.setLiteral("value", str);
Maybe you will use some other predicate, but in order to inject value, you should have ?value in your query as object.
回答2:
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);
}
}
来源:https://stackoverflow.com/questions/42978546/parameterized-sparql-query