参数化SPARQL查询 [英] parameterized SPARQL Query

查看:88
本文介绍了参数化SPARQL查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆