2013-03-04 5 views
8

Supponiamo che io sono un po 'oggetto query jena:Come ottenere tutti gli argomenti di una query Jena?

String query = "SELECT * WHERE{ ?s <some_uri> ?o ...etc. }"; 
Query q = QueryFactory.create(query, Syntax.syntaxARQ); 

Quale sarebbe il modo migliore per ottenere tutti i soggetti delle triple nella query? Preferibilmente senza dover eseguire manualmente l'analisi/manipolazione delle stringhe.

Ad esempio, data una query

SELECT * WHERE { 
    ?s ?p ?o; 
     ?p2 ?o2. 
    ?s2 ?p3 ?o3. 
    ?s3 ?p4 ?o4. 
    <http://example.com> ?p5 ?o5. 
} 

spererei di essere tornato qualche lista che si presenta come

[?s, ?s2, ?s3, <http://example.com>] 

In altre parole, voglio che la lista di tutti i soggetti in una query. Anche avere solo quei soggetti che erano variabili o quelli che erano letterali/uris sarebbe stato utile, ma mi piacerebbe trovare un elenco di tutti gli argomenti nella query.

So che esistono metodi per restituire le variabili di risultato (Query.getResultVars) e alcune altre informazioni (vedere http://jena.apache.org/documentation/javadoc/arq/com/hp/hpl/jena/query/Query.html), ma non riesco a trovare nulla che ottenga specificamente gli argomenti della query (un elenco di tutti i risultati le variabili restituirebbero anche i predicati e gli oggetti).

Qualsiasi aiuto apprezzato.

+0

È la stringa di query fornita o è possibile modificarla? Perché il tuo problema può essere risolto facilmente cambiando la query. – Sentry

+0

Penso di aver finalmente capito cosa intendi. Non vuoi che tutti i soggetti nel risultato, ma tutte le variabili vincolanti per i soggetti nella query, giusto? Se è così, ti preghiamo di renderlo più ovvio nella domanda. – Sentry

+0

perché non itrerating su risultati vars? vuoi creare un tavolo con i risultati vars? se no, per favore, fai un esempio. –

risposta

9

Interessante domanda. Quello che devi fare è passare attraverso la query, e per ogni blocco di tripli scorrere e guardare la prima parte.

Il modo più efficace per farlo è tramite un elemento walker che passerà attraverso ciascuna parte della query. Potrebbe sembrare esagerato nel tuo caso, ma le query possono contenere tutti i tipi di cose, tra cui FILTERs, OPTIONALs e nidificato SELECTs. Usando il walker significa che puoi ignorare quella roba e concentrarti solo su ciò che desideri:

Query q = QueryFactory.create(query); // SPARQL 1.1 

// Remember distinct subjects in this 
final Set<Node> subjects = new HashSet<Node>(); 

// This will walk through all parts of the query 
ElementWalker.walk(q.getQueryPattern(), 
    // For each element... 
    new ElementVisitorBase() { 
     // ...when it's a block of triples... 
     public void visit(ElementPathBlock el) { 
      // ...go through all the triples... 
      Iterator<TriplePath> triples = el.patternElts(); 
      while (triples.hasNext()) { 
       // ...and grab the subject 
       subjects.add(triples.next().getSubject()); 
      } 
     } 
    } 
); 
+0

Quindi, questo ha un senso intuitivo, grazie per aver segnalato 'ElementWalker' e' ElementVisitor's. Tuttavia, questa implementazione non sembra funzionare sulla query sopra (né su qualsiasi altra). Trovo difficile eseguire il debug di questo tipo di override del metodo di visita; Qualche idea su quale potrebbe essere il problema? Ogni volta che provo questo tipo di override, ottengo solo una lista vuota restituita. Qualcuno ha un altro esempio di questo in azione? –

+2

È necessario cercare ElementPathBlock per SPARQL 1.1 e ElementTriplesBlock. Vedi PatternVarsVisitor – AndyS

+0

Ah, naturalmente. La versione corretta sopra funziona per me. – user205512