2013-03-04 12 views
8

Załóżmy, że mam jakiś przedmiot zapytania Jena:Jak zdobyć wszystkie tematy kwerendy Jeny?

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

Jaki byłby najlepszy sposób, aby uzyskać wszystkie tematami trójek w kwerendzie? Najlepiej bez konieczności ręcznego parsowania/manipulowania ciągami.

Na przykład, biorąc pod uwagę zapytanie

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

Mam nadzieję, że wrócił jakieś listy, która wygląda jak

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

Innymi słowy, chcę wykaz wszystkich przedmiotów w zapytaniu. Nawet użyteczne byłyby tylko te tematy, które były zmiennymi lub literałami/uris, ale chciałbym znaleźć listę wszystkich tematów w zapytaniu.

Wiem, że istnieją metody zwracania zmiennych wynikowych (Query.getResultVars) i kilka innych informacji (patrz http://jena.apache.org/documentation/javadoc/arq/com/hp/hpl/jena/query/Query.html), ale nie mogę znaleźć niczego, co pozwoli uzyskać konkretne tematy zapytania (lista wszystkich wyników zmienne zwrócą również predykaty i obiekty).

Każda pomoc doceniona.

+0

Czy podano ciąg zapytania lub czy można go zmienić? Ponieważ twój problem można rozwiązać dość łatwo, zmieniając zapytanie. – Sentry

+0

Myślę, że w końcu zrozumiałem, co masz na myśli. Nie chcesz wszystkich podmiotów w wyniku, ale wszystkie zmienne wiążące dla podmiotów w zapytaniu, prawda? Jeśli tak, prosimy o bardziej oczywiste pytanie. – Sentry

+0

dlaczego nie itrerating vars wyników? Czy chcesz utworzyć tabelę z wynikami vars? jeśli nie, podaj przykład. –

Odpowiedz

9

Interesujące pytanie. To, co musisz zrobić, to przejść przez zapytanie, a dla każdego bloku trójki powtórzyć i przyjrzeć się pierwszej części.

Najbardziej niezawodny sposób to zrobić za pomocą elementu Walker, który przejdzie przez każdą część zapytania. Może się wydawać, że jest w twoim przypadku zawyżone, ale zapytania mogą zawierać różne rzeczy, w tym FILTERs, OPTIONALs i zagnieżdżone SELECTs. Korzystanie z walkera oznacza, że ​​możesz zignorować te rzeczy i skupić się tylko na tym, co chcesz:

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

To intuicyjnie ma sens, dziękuję za wskazanie elementów "ElementWalker" i "ElementVisitor". Jednak ta implementacja nie działa w powyższej kwerendzie (ani żadnej innej). Trudno jest debugować ten rodzaj nadpisywania metody odwiedzin; jakikolwiek pomysł, jaki może być problem? Za każdym razem, gdy próbuję tego rodzaju przesłonięcia, otrzymuję pustą listę zwróconą. Czy ktoś ma inny przykład tego działania? –

+2

Musisz szukać w ElementPathBlock dla SPARQL 1.1 oraz ElementTriplesBlock. Oczywiście, zobacz PatternVarsVisitor – AndyS

+0

Ah. Poprawiona wersja powyżej działa dla mnie. – user205512

Powiązane problemy