alem
alem

Reputation: 5

How to get the first element from Jena SPAQL Resultset

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...

Upvotes: 0

Views: 721

Answers (1)

Joshua Taylor
Joshua Taylor

Reputation: 85883

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() );

Upvotes: 3

Related Questions