Как получить UpdateExpr при выполнении запроса вставки RDF4J

#java #parsing #sparql #rdf4j

#java #синтаксический анализ #sparql #rdf4j

Вопрос:

проблема с запросом вставки, не удается проанализировать простые инструкции

Пример: запрос:

 PREFIX dc: <http://purl.org/dc/elements/1.1/>
INSERT DATA 
{
    <http://example/book1> dc:title "A new book";
                           dc:creator "A.N.Other" .
}
  

Результат:

 PREFIX dc: <http://purl.org/dc/elements/1.1/> 
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> 
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> 
PREFIX sesame: <http://www.openrdf.org/schema/sesame#> 
PREFIX owl: <http://www.w3.org/2002/07/owl#> 
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> 
PREFIX fn: <http://www.w3.org/2005/xpath-functions#> 
 <http://example/book1> dc:title "A new book" ; dc:creator "A.N.Other" .
  

Но если я разберу что-то более сложное, все будет хорошо.

запрос:

 PREFIX dc:  <http://purl.org/dc/elements/1.1/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>

INSERT 
  { GRAPH <http://example/bookStore2> { ?book ?p ?v } }
WHERE
  { GRAPH  <http://example/bookStore>
       { ?book dc:date ?date .
         FILTER ( ?date > "1970-01-01T00:00:00-02:00"^^xsd:dateTime )
         ?book ?p ?v
  } }
  

Результат:

 StatementPattern FROM NAMED CONTEXT
   Var (name=book)
   Var (name=p)
   Var (name=v)
   Var (name=_const_f1165b11_uri, value=http://example/bookStore2, anonymous)

Modify
   StatementPattern FROM NAMED CONTEXT
      Var (name=book)
      Var (name=p)
      Var (name=v)
      Var (name=_const_f1165b11_uri, value=http://example/bookStore2, anonymous)
   Filter
      Compare (>)
         Var (name=date)
         ValueConstant (value="1970-01-01T00:00:00-02:00"^^<http://www.w3.org/2001/XMLSchema#dateTime>)
      Join
         StatementPattern FROM NAMED CONTEXT
            Var (name=book)
            Var (name=_const_9b277d39_uri, value=http://purl.org/dc/elements/1.1/date, anonymous)
            Var (name=date)
            Var (name=_const_39534d41_uri, value=http://example/bookStore, anonymous)
         StatementPattern FROM NAMED CONTEXT
            Var (name=book)
            Var (name=p)
            Var (name=v)
            Var (name=_const_39534d41_uri, value=http://example/bookStore, anonymous)
  

Мне нужно получить что-то подобное в первом случае. Что я делаю не так?

Java-код для выполнения этих запросов:

 String query = ...
SPARQLParser parser = new SPARQLParser();
ParsedUpdate q2 = parser.parseUpdate(query, null);
Iterator var2 = q2.getUpdateExprs().iterator();
UpdateExpr updateExpr = (UpdateExpr)var2.next();
System.out.println(updateExpr);
  

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

1. Я этого не понимаю. Что не работает со вторым запросом? Для первого запроса вы показали результат RDF, но для второго запроса вы показали план выполнения запроса. Вы выполняете оба запроса одинаково? Я думаю, что нет

2. @AKSW Мне нужно получить план выполнения для первого запроса. Второй результат запроса в порядке.

3. @AKSW «Вы выполняете оба запроса одинаково? «конечно.

4. Я вижу. Основное отличие заключается в том, что первый запрос будет преобразован в объект типа org.eclipse.rdf4j.query.algebra.InsertData — это статические данные, таким образом, вы не увидите здесь инструкций. Второй запрос, с другой стороны, преобразуется в org.eclipse.rdf4j.query.algebra.Modify объект, который на самом деле содержит те TupleExp объекты, которые вы видите визуализированными в виде дерева, подобного этим StatementPattern объектам.

5. @ГеворгАрутюнян зачем именно вам это вообще нужно — я имею в виду, что вы планируете делать с этими «простыми инструкциями»? Причина, по которой я спрашиваю, заключается в том, что если мы понимаем, что вы пытаетесь сделать, мы можем порекомендовать другие / лучшие способы достижения этого.

Ответ №1:

Как указано в комментариях, блок данных для INSERT DATA обновления SPARQL хранится внутри в виде (нерасчлененной) строки. Если вы хотите обработать его дальше, у вас есть пара вариантов.

Один из вариантов — фактически просто выполнить обновление, например, для временного / пустого хранилища в памяти, а затем просто извлечь инструкции из этого хранилища:

  String update = "INSERT DATA { .... }";
 Repository tempRep = new SailRepository(new MemoryStore());
 tempRep.init();
 try(RepositoryConnection conn = tempRep.getConnection()) {
     conn.prepareUpdate(update).execute());
     Model statements = QueryResults.asModel(conn.getStatements(null, null, null));
 }
  

Другой вариант, который, возможно, более масштабируемый, заключается в том, чтобы просто извлечь блок данных в виде строки и передать его через анализатор. SPARQLUpdateDataBlockParser Специально существует для этой цели:

 InsertData insertDataExpr = (InsertData)updateExpr;

RDFParser parser = new SPARQLUpdateDataBlockParser();
StatementCollector handler = new StatementCollector();
parser.setRDFHandler(handler);

parser.parse(new StringReader(insertDataExpr.getDataBlock()), "");

Collection<Statement> stmts = handler.getStatements();