问题
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