Bind function in SPARQL with Jena API

℡╲_俬逩灬. 提交于 2019-12-25 12:48:08

问题


I use jena for android to send a query to DBpedia. This is my query:

    protected Vector<List> doInBackground(String... keyword) {
                VecDBpedia=new Vector();
                vecurl= new ArrayList();
                 int i=0;
                 ResultSet results,re = null ;
                 QueryExecution exec = null ;
    try{           
              do{
               if(i!=VectorKeyWords.size())
                 {System.out.println(keyword[i]);
                String sparqlQuery=

                        "PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n" +
                            "PREFIX dbo:     <http://dbpedia.org/ontology/>\n" +
                            "PREFIX rdfs:   <http://www.w3.org/2000/01/rdf-schema#> \n" +
                            "prefix foaf: <http://xmlns.com/foaf/0.1/> \n"+
                            "PREFIX dbpprop: <http://dbpedia.org/property/>\n"+


                            "select distinct ?nbr ?Nom ?resource ?url where {\n" +
                            "?resource rdfs:label ?Nom.\n" +
                                "?resource foaf:isPrimaryTopicOf ?url.\n" +
                                 "?resource dbo:abstract ?resume.\n"+
                                "FILTER  langMatches( lang(?Nom), \"EN\") .\n" +
                                "FILTER langMatches( lang(?resume), \"EN\" )\n"+
                                "?Nom <bif:contains> \"Apple\".\n"+
                                "bind(strlen(replace(replace(Lcase(?resume), \"jobs\", \"_\"),\"[^_]\", \"\")) as ?nbr )\n"+
                                "filter (?nbr >= 1)\n"+
                                "}" ;

            String service=  "http://dbpedia.org/sparql";

            Query qur=QueryFactory.create(sparqlQuery,Syntax.syntaxARQ);
            System.out.print("sparqlQuery"+sparqlQuery);

             exec =QueryExecutionFactory.sparqlService(service,qur );
             System.out.print("qur"+qur);
              re =exec.execSelect();
              System.out.print("re"+re);

            i++;
            System.out.println(re.hasNext());}  

              } while(re.hasNext()==false && i<VectorKeyWords.size());
          if(i==VectorKeyWords.size())  //si aucun des mot clé ne se trouve dans DBpedia
     { System.out.println("Aucun mot clé ne correspond à une entrée en DBpedia");
     cancel(true);// A vérifier
     finish();}


     results = ResultSetFactory.copyResults( re );
     ResultSetFormatter.out( results );
     while ( results.hasNext() ) {
                ArrayList<String>   listDBpediaResource=new ArrayList();
                QuerySolution node=  results.next();

                RDFNode colonne1=node.get( "Nom" );
                RDFNode colonne2=node.get( "resource" );
                RDFNode colonne3=node.get( "url" );

                // RDFNode s2= results.next().get( "url" );
                 listDBpediaResource.add(colonne2.toString());
                 listDBpediaResource.add(colonne3.toString());
                 listDBpediaResource.add(colonne1.toString());

                 VecDBpedia.add(listDBpediaResource);
                 vecurl.add(colonne3.toString());//creer un vecteur contenant les url de chaque ressource condidat de dbpedia

                }


            }  catch (Exception  e) {
                 e.printStackTrace();
            }
            finally{exec.close();}

            return VecDBpedia;
        }
         ;

this query works at SPARQL endpoint, and also in a java application, but does'nt work in android application.

I get this message while executing the code:

W/System.err(8123): com.hp.hpl.jena.query.QueryParseException: Lexical error at line 13, column 5.  Encountered: "(" (40), after : "bind"
W/System.err(8123):     at com.hp.hpl.jena.sparql.lang.ParserARQ.perform(ParserARQ.java:95)
W/System.err(8123):at com.hp.hpl.jena.sparql.lang.ParserARQ.parse(ParserARQ.java:39)
W/System.err(8123):     at com.hp.hpl.jena.query.QueryFactory.parse(QueryFactory.java:129)
W/System.err(8123):     at com.hp.hpl.jena.query.QueryFactory.create(QueryFactory.java:72)
W/System.err(8123):     at com.hp.hpl.jena.query.QueryFactory.create(QueryFactory.java:43)
W/System.err(8123):     at com.example.testtvprg.MainActivity$AsyncDBpedia.doInBackground(MainActivity.java:426)
W/System.err(8123):     at com.example.testtvprg.MainActivity$AsyncDBpedia.doInBackground(MainActivity.java:1)
W/System.err(8123):     at android.os.AsyncTask$2.call(AsyncTask.java:287)
W/System.err(8123):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
W/System.err(8123):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
 W/System.err(8123):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
W/System.err(8123):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
W/System.err(8123):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
W/System.err(8123):     at java.lang.Thread.run(Thread.java:856)

I think that it's a problem of jena or arq version, but i don't know how to correct it. Any one can help me please. Thanks


回答1:


instead of

QueryExecution queryExecution =
QueryExecutionFactory.sparqlService(ontology_service, query);

try to use :

QueryExecution execution = new QueryEngineHTTP(ontology_service, query);

i assume you use it cause your code is incomplete at the moment (it only shows your String query = ...)

let me know if that works ;)

EDIT :

maybe try to follow my own query and adapt it to your needs :

private String entityQuery(String params) {
        return
                "PREFIX ontology: <http://dbpedia.org/ontology/>\n" +
                        "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n" +
                        "PREFIX foaf: <http://xmlns.com/foaf/0.1/>\n" +
                        "SELECT DISTINCT ?thumb ?entity ?desc ?label ?pic \n" +
                        " WHERE\n" +
                        " {\n" +
                        "?entity  a ontology:" + category + ";\n" +
                        "ontology:abstract ?desc;\n" +
                        "rdfs:label ?label.\n" +
                        "OPTIONAL{?entity foaf:depiction ?pic;" +
                        "ontology:thumbnail ?thumb}. " +
                        "FILTER(langmatches(lang(?desc),\"en\")" +
                        " && langmatches(lang(?label),\"en\"))\n" +
                        "?desc <bif:contains> \"'" + params + "'\"\n" +
                        "}ORDER BY ?label LIMIT 10000 OFFSET 0";
    }

and here is the QueryExecution in my doinBackground() asynctask

Query query = QueryFactory.create(entityQuery(params[0]));
        QueryExecution execution = new QueryEngineHTTP("http://dbpedia.org/sparql", query);
        try {
            ResultSet results = execution.execSelect();

            while (results.hasNext()) {

                Entity a = new Entity();
                QuerySolution row = results.nextSolution();

                if (row.getResource("pic") != null)
                    a.setDepiction(row.get("pic").toString().replace("http", "https"));
                if (row.getResource("thumb") != null)
                    a.setThumb(row.get("thumb").toString().replace("http", "https"));

                a.setTitle(row.getLiteral("label").getString());

                a.setSummary(row.getLiteral("desc").getString());
                fragmentResults.getEntities().add(a);
            }
            execution.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

and i noticied that you removed the bind(... part of your query, so i recommend you to try QueryEngineHTTP now it should work

i also wonder why youre using RDFNODE?

Edit2

if you want to filter words that contains also i suggest you to do your query like that :

PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX dbpedia-owl:<http://www.dbpedial.org/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> 
PREFIX foaf: <http://xmlns.com/foaf/0.1/>

    select distinct ?resource ?url ?resume where {
       ?resource rdfs:label ?Nom.
       ?resource foaf:isPrimaryTopicOf ?url.
       ?resource dbo:abstract ?resume.
       FILTER langMatches( lang(?Nom), "EN" )
       FILTER langMatches( lang(?resume), "EN" )
       ?Nom <bif:contains> "'apple'".
       ?resume <bif:contains> "'Jobs'"


    }

edit3

 protected Vector<List> doInBackground(String... keyword) {
                    VecDBpedia=new Vector();
                    vecurl= new ArrayList();
                     int i=0;
                     ResultSet results,re = null ;
                     QueryExecution exec = null ;
        try{           
                  do{
                   if(i!=VectorKeyWords.size())
                     {System.out.println(keyword[i]);
                    String sparqlQuery=
     PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#>
    PREFIX dbpedia-owl:<http://www.dbpedial.org/>
    PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> 
    PREFIX foaf: <http://xmlns.com/foaf/0.1/>

        select distinct ?resource ?url ?resume where {
           ?resource rdfs:label ?Nom.
           ?resource foaf:isPrimaryTopicOf ?url.
           ?resource dbo:abstract ?resume.
           FILTER langMatches( lang(?Nom), "EN" )
           FILTER langMatches( lang(?resume), "EN" )
           ?Nom <bif:contains> "'apple'".
           ?resume <bif:contains> "'Jobs'"


        }

                String service=  "http://dbpedia.org/sparql";

                Query qur=QueryFactory.create(sparqlQuery,Syntax.syntaxARQ);
                System.out.print("sparqlQuery"+sparqlQuery);

                 exec =QueryExecutionFactory.sparqlService(service,qur );
                 System.out.print("qur"+qur);
                  re =exec.execSelect();
                  System.out.print("re"+re);

                i++;
                System.out.println(re.hasNext());}  

                  } while(re.hasNext()==false && i<VectorKeyWords.size());
              if(i==VectorKeyWords.size())  //si aucun des mot clé ne se trouve dans DBpedia
         { System.out.println("Aucun mot clé ne correspond à une entrée en DBpedia");
         cancel(true);// A vérifier
         finish();}


         results = ResultSetFactory.copyResults( re );
         ResultSetFormatter.out( results );
         while ( results.hasNext() ) {
                    ArrayList<String>   listDBpediaResource=new ArrayList();
                    QuerySolution node=  results.next();

                    RDFNode colonne1=node.get( "Nom" );
                    RDFNode colonne2=node.get( "resource" );
                    RDFNode colonne3=node.get( "url" );

                    int matches = 0;
                    Matcher matcher = Pattern.compile("Jobs",Pattern.CASE_INSENSITIVE).matcher(colonne2.toString());
                    while (matcher.find()) matches++;
                Log.d("numMatches","jobs"+"("+matches+")");


                    // RDFNode s2= results.next().get( "url" );
                     listDBpediaResource.add(colonne2.toString());
                     listDBpediaResource.add(colonne3.toString());
                     listDBpediaResource.add(colonne1.toString());




                     VecDBpedia.add(listDBpediaResource);
                     vecurl.add(colonne3.toString());//creer un vecteur contenant les url de chaque ressource condidat de dbpedia

                    }


                }  catch (Exception  e) {
                     e.printStackTrace();
                }
                finally{exec.close();}

                return VecDBpedia;
            }
             ;

so i added this to your asynctask :

int matches = 0;
                        Matcher matcher = Pattern.compile("Jobs", Pattern.CASE_INSENSITIVE).matcher(colonne2.toString());
                        while (matcher.find()) matches++;
                    Log.d("numMatches","jobs"+"("+matches+")");

regarding the logger, it will return you the number of matches of "Jobs into the colonne2 string... can you test it please? also check at your logcat to know if the number is correct... with this technique you can easy filter example like that

int matches = 0;
                    Matcher matcher = Pattern.compile("Jobs",Pattern.CASE_INSENSITIVE).matcher(colonne2.toString());
                    while (matcher.find()) matches++;
                Log.d("numMatches","jobs"+"("+matches+")");


                    // RDFNode s2= results.next().get( "url" );
                  if(matches > 1)
                     {
                     listDBpediaResource.add(colonne2.toString());
                     listDBpediaResource.add(colonne3.toString());
                     listDBpediaResource.add(colonne1.toString());
                     }



回答2:


Thinks to all those wanted to help me. I finally decide to change the function BIND of the query, because it doesn't work with QueryExecutionFactory.sparqlService neither with QueryEngineHttp. It's a temporary solution, because may be i would need to other functions that will have the same problem. If anyone knows a solution , i will be grateful.



来源:https://stackoverflow.com/questions/33861187/bind-function-in-sparql-with-jena-api

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!