Nesting of FLWOR expressions
For the illustration of nested FLWOR expressions in return clauses, the query pattern of the pivoting of XML documents is used as an example. Concretely, a document is to be generated which does no longer assign the findings to each individual patient, but which lists the patients affected by each existing finding. The following schematic diagram demonstrates the problem of the pivoting.
Image: Pivoting of XML documents
The result document is specified by a nested FLWOR expression which, at first, constructs the new root and interprets the result of the following FLWOR expression as subelements. Therein, all documents containing patient data are bound to the $c variable. In the second step, all <Findings> elements contained in the patient data are successively determined by the appropriate path expression.
Since obviously several patients may contract the same illness and, as a consequence, may have the same finding, with the call of the fn:distinct-values() function an explicit duplicate elimination is enforced. For each determined finding, the return clause is evaluated and the finding is outputted. Within the <Patients> elements, in turn, a new evaluation context is opened in which as expression not only the dereferencing of a variable exists, but a renewed FLWOR expression. This expression returns the names of the patients which suffer from the currently regarded and accordingly diagnosed illness (comparison in the path expression with the current allocation of the $b variable).
<Findings>
{
let $c := fn:collection("Patients")
for $f in fn:distinct-values($c//Finding)
order by $f
return
<Finding>
<Designation>{ $f }</Designation>
<Patients>
{
for $p in $c/element(*,Patient_T)[Examination/Finding = $f]
order by $p/Name/LastName, $p/Name/FirstName
return $p/Name
}
</Patients>
</Finding>
}
</Findings>
As a remark the implicit process of the atomization when determining different findings is important. So, the fn:distinct-values($c//Finding) expression in the above example does not return all the different <Findings> elements, but all textual descriptions of findings. As a consequence, the implictily performed atomization may also be enforced explicitly by using the fn:text() function, so that fn:distinct-values($c//Finding/fn:text()) would be equivalent to the above expression.
In conclusion, with this form of nesting a join with regard to the same data stock (self-join) is formulated. Joins with different semantics will be explained on the following pages.
Source: "XQuery – Grundlagen und fortgeschrittene Methoden", dpunkt-Verlag, Heidelberg (2004)
<< back | next >> |