2015-11-22 7 views
0

Я использую jena для android для отправки запроса в DBpedia. Это мой запрос:Функция привязки в SPARQL с API Jena

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; 
     } 
     ; 

этот запрос работает в SPARQL конечной точке, а также в приложении Java, но does'nt работа в андроиде приложения.

я получаю это сообщение при выполнении кода:

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) 

Я думаю, что это проблема Jena или ARQ версии, но я не знаю, как это исправить. Любой может мне помочь. Благодаря

+0

Любой ответ пожалуйста !! – faffou

+0

Порт Android (который отдельно от проекта Apache Jena) использует более старый ARQ. Возможно, BIND не поддерживается. – AndyS

+0

'' специфичен для Virtuoso. – AndyS

ответ

0

вместо

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

попытаться использовать:

QueryExecution execution = new QueryEngineHTTP(ontology_service, query); 

я предполагаю, что вы используете это может вызвать ваш код является неполным в данный момент (это только показывает ваше String query = ...)

дайте мне знать, если это работает;)

EDIT:

возможно попытаться следовать своему собственному запросу и адаптировать его к вашим потребностям:

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"; 
    } 

и здесь является QueryExecution в моей 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(); 
     } 

и я что вы удалили привязку (... часть вашего запроса, поэтому я рекомендую вам попробовать QueryEngineHTTP теперь он должен работать

Я также удивляюсь, почему вы используете RDFNODE?

Edit2

, если вы хотите, чтобы фильтровать слова, которые содержит также я предлагаю вам сделать запрос так:

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; 
      } 
      ; 

так я добавил это для вашей асинтезы:

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

относительно регистратора, он вернет вам количество совпадений «Задания в строку colonne2 ... вы можете проверить его? Кроме того, проверьте на вашем LogCat знать, если число правильно ... с этой техникой, вы можете простой пример фильтра, как этот

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()); 
        } 
+0

не работает. Я обновлю свой код и сделаю все функции. – faffou

+0

это моя проблема: функция BIND. он не работает при выполнении в коде Android. Принимая во внимание, что он хорошо работает в других запросах без BIND. – faffou

+0

Что вы пытаетесь сделать со связью? – Noj

0

Думает всех тех, кто хотел помочь мне.Я, наконец, решил изменить функцию BIND запроса, потому что он не работает с QueryExecutionFactory.sparqlService ни с QueryEngineHttp. Это временное решение, потому что, возможно, мне понадобятся другие функции, которые будут иметь одинаковую проблему. Если кто-нибудь знает решение, я буду благодарен.

Смежные вопросы