I have a SPARQL query over a Jena model returning a single result. How can I access that result for I cannot iterate because only one element? I have tried 2 options but all failed. I used the ResultSetFormatter to convert result to JSONObject but I found that the keys are not my variables. Moreover, I tried to convert it to QuerySolution list using toList() method but it is returning empty list. Any help?
public void insertMedcationContext(JSONObject medcontext) {
connection.getDataset().begin(ReadWrite.WRITE);
Model model = connection.getDataset().getDefaultModel();
String medActivityQuery = "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n"
+ "PREFIX fn: <http://www.w3.org/2005/xpath-functions#>\n"
+ "PREFIX medication:<http://www.cs.kaist.ac.kr/medication/ontology#>\n"
+ "PREFIX resource:<http://www.cs.kaist.ac.kr/medication/resource#>\n"
+ "PREFIX time:<http://www.w3.org/2006/time#>\n"
+ "SELECT ?activity ((?deschour - ?timestamp) AS ?gap) (fn:abs(?gap)AS ?gapabsolute)\n"
+ "WHERE\n"
+ "{?activity rdf:type medication:MedicationActivity .\n"
+ "?activity medication:belongsTo ?schedule .\n"
+ "?activity medication:expectedTime ?time .\n"
+ "?time time:hasTimeDescription ?desc .\n"
+ "?desc time:year ?descyear .\n"
+ "?desc time:month ?descmonth .\n"
+ "?desc time:day ?descdate .\n"
+ "?desc time:hour ?deschour .\n"
+ "}\n"
+ "ORDER BY (?gapabsolute)\n"
+ "LIMIT 1";
try {
Resource schedule = model.createResource(
nameSpace + medcontext.getString("schedule"),
MEDICATION.Schedule);
Resource scheduleResource = model.getResource(schedule.getURI());
ParameterizedSparqlString parameterizedQuery = new ParameterizedSparqlString(
medActivityQuery);
parameterizedQuery.setParam("schedule", scheduleResource);
JSONObject timestamp = new JSONObject();
timestamp = medcontext.getJSONObject("exacttime");
parameterizedQuery.setLiteral("descyear",Integer.toString(timestamp.getInt("year")),XSDDatatype.XSDgYear);
parameterizedQuery.setLiteral("descmonth",Integer.toString(timestamp.getInt("month")),XSDDatatype.XSDgMonth);
parameterizedQuery.setLiteral("descdate",Integer.toString(timestamp.getInt("date")),XSDDatatype.XSDgDay);
parameterizedQuery.setLiteral("timestamp",Integer.toString(timestamp.getInt("hour")),XSDDatatype.XSDnonNegativeInteger);
Query query = QueryFactory.create(parameterizedQuery.toString());
QueryExecution qe = QueryExecutionFactory.create(query, model);
try {
ResultSet result = qe.execSelect();
String text = ResultSetFormatter.asText(result);
System.out.println(text);
ByteArrayOutputStream b = new ByteArrayOutputStream();
ResultSetFormatter.outputAsJSON(b, result);
JSONObject jsonResult = new JSONObject (b.toString());
System.out.print(jsonResult);
List <QuerySolution> resultList = ResultSetFormatter.toList(result);
// Get the right medication activity from the model for which context is incoming
Resource rightActivity = null;
QuerySolution row = resultList.get(0);
rightActivity = row.getResource("activity");
System.out.print(rightActivity.toString());
resultList is empty yet there is one result...
ResultSets are, by default, produced on demand. You can only iterate through them once, and then the results are consumed. After you do
ResultSet result = qe.execSelect();
String text = ResultSetFormatter.asText(result);
you probably can't get any results from doing
ResultSetFormatter.outputAsJSON(b, result);
or
ResultSetFormatter.toList(result);
Instead, you should copy the ResultSet with, e.g.,
ResultSet results = ResultSetFactory.copyResults( qe.execSelect() );