Получите несколько столбцов в результирующем наборе из sparql в Netbeans JTable

#java #sparql #jena #protege

Вопрос:

Я пытаюсь выбрать несколько столбцов в результирующем наборе Jena, а затем привязать их к таблице Java.

Когда я выбираю только один столбец, результирующий набор работает нормально, но когда я выбираю два столбца, в результирующем наборе нет ни одной строки, хотя в нем есть только столбцы:

Вот мой Java-код:

 private void btnExecuteSPARQLActionPerformed(java.awt.event.ActionEvent evt) {                                                 
        
        try 
        {           
            System.out.println("Executing SPARQL...");  // get the name list query
            String queryString;
            queryString = "PREFIX ssuet:<http://www.semanticweb.org/alinaanjum2/ontologies/2021/6/untitled-ontology-4#> "
                             txtQuery.getText();

            com.hp.hpl.jena.query.ResultSet results = OpenOWL.ExecSparQl(queryString); //all method ExecSparQl from OpenOWL class
    
            ResultSetFormatter.out(results);

            // It creates and displays the table
            JTable table = new JTable(buildTableModel(results));
            JOptionPane.showMessageDialog(null, new JScrollPane(table));
        } 
        catch (Exception ex) 
        {
           System.out.println(ex);
        }
    }                                                
    
    //CODE ADDITION BY ALINA ANJUM STARTED ON 03-AUGUST-2021
   public static DefaultTableModel buildTableModel(com.hp.hpl.jena.query.ResultSet rs)
        throws SQLException {

         List<String> metaData = rs.getResultVars();

    // names of columns
    Vector<String> columnNames = new Vector<String>();
    int columnCount = metaData.size();
    
       System.out.println(columnCount);
       
    for (int column = 0; column <columnCount; column  ) 
    {
        columnNames.add(metaData.get(column));
    }

    // data of the table
    Vector<Vector<Object>> data = new Vector<Vector<Object>>();
    
    while (rs.hasNext()) 
    {
        QuerySolution sol = rs.nextSolution();     
        
        Vector<Object> vector = new Vector<Object>();
        
        for (int columnIndex = 0; columnIndex < columnCount; columnIndex  ) 
        {
            //vector.add(rs.getObject(columnIndex));
            String columnName = columnNames.get(columnIndex);   
            vector.add(sol.getLiteral(columnName).getString());
        }
        data.add(vector);
    }

    return new DefaultTableModel(data, columnNames);

}
 

Следующий запрос идеально возвращает значения:

 SELECT (str(?x) as ?name)
WHERE {
   ?Person ssuet:hasname ?x.
}
 

Следующий запрос отлично работает в Protege, но не возвращает значения в результирующем наборе в Java:

 SELECT (str(?x) as ?name)
(str(?y) as ?phone)
WHERE {
   ?Person ssuet:hasname ?x.
?Person ssuet:hasPhoneNumber ?y.
}
 

Снимок экрана с выводом в Netbeans:

введите описание изображения здесь

Результаты для 2-го запроса в protege:

введите описание изображения здесь

Комментарии:

1. com.hp.hpl.jena.query — эта версия Йены древняя. В настоящее время Jena работает над версией 4.2.0.

2. кроме того, вы должны использовать Java 11, опустить Vector класс, следовать своему собственному соглашению об именовании и использовать hasName (стиль верблюжьего регистра)

3. если ваш второй запрос ничего не возвращает, даже на консоли Netbeans, то данные просто не такие, как в Protege, и запрос не совпадает. Вы проверили это с помощью текстового редактора? Или просто распечатать тройку через Jena API?

4. @Неинформированный пользователь не могли бы вы поделиться полным руководством по новой версии Jena? Я новичок в этом

5. просто используйте Apache Jena с Maven (документы доступны онлайн), а не такой 6-летний сторонний проект, как github.com/softiecode/QueryExpansion если вам не нужно то, что они предоставляют в качестве функций. И они не делают ничего, кроме как загружают онтологию в OntModel и затем запускают запрос. Я бы предложил сделать это на родном коде Jena и использовать последнюю версию 4.2.0

Ответ №1:

ResultSets являются итераторами.

Вызов ResultSetFormatter.out(results) исчерпывает итератор (больше строк нет).

Если вы хотите использовать результат дважды, используйте ResultSetFactory.makeRewindable его, чтобы получить набор результатов, который можно сбросить до начала.

Комментарии:

1. правильно, ни один из двух quries не будет отображаться как JTable — но afaik вопрос также заключался в том, почему второй запрос вообще не показывает никакого набора результатов, даже не в CLI — см. Первый снимок экрана, он возвращает полную таблицу в CLI, но только заголовок для второго

2. спасибо @AndyS, но проблема во 2-м запросе. это даже не возвращается в ResultSetFormatter, как сказал неинформированный пользователь.