Schachtelung von FLWOR-Ausdrücken
Zur Illustration von geschachtelten FLWOR-Ausdrücken in return-Klauseln wird exemplarisch das Anfragemuster der Pivotierung von XML-Dokumenten herangezogen. Konkret gilt es, ein Dokument zu erstellen, welches nicht mehr jedem Patienten einzeln seine Befunde zuordnet, sondern das zu jedem existierenden Befund die davon betroffenen Patienten auflistet. Die folgende Abbildung verdeutlicht das Problem der Pivotierung schematisch.
Abb. Pivotieren von XML-Dokumenten
Das Ergebnisdokument wird durch einen geschachtelten FLWOR-Ausdruck spezifiziert, welcher zunächst die neue Wurzel konstruiert und das Ergebnis des nachfolgenden FLWOR-Ausdrucks als Unterelemente interpretiert. Darin werden zunächst alle Dokumente, die Patientendaten enthalten, an die Variable $c gebunden. Im zweiten Schritt werden sukzessive alle Befunde-Elemente, die in Patientendaten enthalten sind, durch einen entsprechenden Pfadausdruck ermittelt.
Da offensichtlicherweise mehrere Patienten an der gleichen Krankheit erkrankt sein können und damit den gleichen Befund aufweisen können, wird mit dem Aufruf der Funktion fn:distinct-values() eine explizite Duplikateliminierung erzwungen. Für jeden ermittelten Befund wird die return-Klausel ausgewertet und der Befund ausgegeben. Innerhalb des <Patienten>-Elementes wird wiederum ein neuer Auswertungskontext eröffnet, in dem als Ausdruck nicht nur die Dereferenzierung einer Variablen, sondern ein erneuter FLWOR-Ausdruck existiert. Dieser gibt die Namen der Patienten zurück, die an der aktuell betrachteten und entsprechend diagnostizierten Krankheit (Vergleich im Pfadausdruck mit der aktuellen Belegung der Variablen $b) leiden.
<Befunde>
{
let $c := fn:collection("Patienten")
for $b in fn:distinct-values($c//Befund)
order by $b
return
<Befund>
<Bezeichnung>{ $b }</Bezeichnung>
<Patienten>
{
for $p in $c/element(*,Patient_T)[Untersuchung/Befund = $b]
order by $p/Name/Nachname, $p/Name/Vorname
return $p/Name
}
</Patienten>
</Befund>
}
</Befunde>
Als Anmerkung ist der implizite Vorgang der Atomisierung bei der Bestimmung unterschiedlicher Befunde wichtig. So liefert der Ausdruck fn:distinct-values($c//Befund) im obigen Beispiel nicht alle unterschiedlichen Befunde-Elemente, sondern alle textuellen Befundbeschreibungen. Die implizit durchgeführte Atomisierung kann somit auch explizit durch Verwendung der Funktion fn:text() erzwungen werden, so dass fn:distinct-values($c//Befund/fn:text()) zu obigem Ausdruck äquivalent wäre.
Zusammenfassend ist festzuhalten, dass mit dieser Form der Schachtelung ein Verbund mit Bezug auf den gleichen Datenbestand (Eigenverbund) formuliert wird. Verbundoperationen mit den unterschiedlichen Semantiken werden ausführlich im Folgenden diskutiert.
Quelle: "XQuery – Grundlagen und fortgeschrittene Methoden", dpunkt-Verlag, Heidelberg (2004)
<< zurück | vor >> |