4.2.2.4 - Expressions FLWOR
Les expressions FLWOR són la part més potent d’XQuery. Estan formades per cinc instruccions opcionals que permeten fer les consultes i alhora processar-les per seleccionar els ítems que interessen d’una seqüència.
Clàusula | Ús | |
---|---|---|
f | for | Permet recórrer una seqüència, agafant cada vegada un element d'aquesta |
l | let | Serveix per assignar valors a una variable |
w | where | Permet filtrar els resultats segons condicions |
o | order by | Ordena els resultats abans de mostrar-los |
r | return | Retorna el resultat de tota l’expressió |
"FOR ... RETURN"
La instrucció for es fa servir per avaluar individualment cadascun dels resultats d’una seqüència de nodes. En un for es defineixen dues coses:
-
Una variable, que serà la que anirà agafant els elements de la seqüència un per un.
-
La paraula clau in, en la qual es defineix quina és la seqüència d’elements per processar.
La manera més senzilla d’expressió FLWOR és combinar el for amb el return per retornar els valors obtinguts de manera seqüencial:
generarà:
Les seqüències de valors poden ser de qualsevol tipus. Per exemple, poden ser números. Així, el següent exemple:
generarà:
O bé una seqüència de nodes, per mig d'una expressió XPath. Per exemple amb l’expressió següent capturem una seqüència de nodes i els fem servir per obtenir-ne el cognom:
generarà:
<cognoms>Alegre</cognoms>
</alumne>
<alumne>
<cognoms>Balaguer</cognoms>
</alumne>
<alumne>
<cognoms>Centelles</cognoms>
</alumne>
Es pot veure que els valors del return s’han anat processant un per un i per aquest motiu es repeteixen les etiquetes <alumne>.
Un aspecte important és que no cal que el for siga la primera expressió de la consulta. També es pot posar com a paràmetre en una funció XPath.
Per exemple, l’expressió següent ens tornarà el nombre d’alumnes:
3
En el for es pot incloure l’operador at, que permet obtenir la posició del node que s’està processant. Amb aquest operador podem fer que aparega el número d’ordre en els resultats.
que donarà
<alumne numero="2">Balaguer</alumne>
<alumne numero="3">Centelles</alumne>
"FOR NIUAT" ("anidat")
Les ordres for es poden posar unes dins d'unes altres, d’una manera similar a com ho fa SQL amb les subconsultes. Així es poden aconseguir resultats més complexos que es basen en els resultats obtinguts anteriorment.
<persona>
<nom>Albert</nom>
</persona>
<persona>
<nom>Bernat</nom>
</persona>
<persona>
<nom>Joan</nom>
</persona>
Aquesta sentència anterior queda un poc pobra, ja que en el document hi ha molt poques dades.
Un exemple un poc més complet (i comprensiu) seria el següent:
return
<ruta>
<nomRuta>
{ $selec/nom/text() }
</nomRuta>
<punts>
{
for $selec2 in $selec//punt
return <punt> {$selec2/nom/text()} </punt>
}
</punts>
</ruta>
que donaria el sagüent resultat:
...
LET
Ens permet declarar variables i assignar-los un valor. Sobretot es fa servir per guardar valors que s’han de fer servir més tard.
En les expressions FLWOR hi pot haver tants let com calga.
<nom>Albert: 6</nom>
<nom>Bernat: 3</nom>
<nom>Joan: 8</nom>
S’ha d’anar amb compte amb let perquè el seu funcionament és molt diferent del de for:
-
for s’executa per a cada membre d’una seqüència.
-
let fa referència al seu valor en conjunt. Si és una seqüència, el que es processa són tots els valors de cop.
Podem veure la diferència amb un exemple. Aquesta instrucció amb for:
Dóna:
<nom>Albert</nom>
</persona>
<persona>
<nom>Bernat</nom>
</persona>
<persona>
<nom>Joan</nom>
</persona>
I en canvi amb let:
Donarà:
<nom>Albert</nom>
<nom>Bernat</nom>
<nom>Joan</nom>
</persona>
Els resultats són bastant diferents! Es pot veure clarament que let ha tractat tots els valors de cop.
WHERE
La instrucció where és la part que indicarà quin filtre s’ha de posar a les dades rebudes abans d’enviar-les a la sortida del return. Normalment en el filtre es fa servir algun tipus de predicat XPath:
<nom>Albert</nom>
<nom>Joan</nom>
Com que XPath forma part d’XQuery moltes vegades el mateix filtre es pot definir de diverses maneres. Per exemple, aquesta expressió és equivalent a l’anterior:
Això sí, en un where hi pot haver tantes condicions com faça falta simplement encadenant-les amb les operacions lògiques and, or o not().
Aquesta expressió retorna el cognom dels alumnes que han aprovat i que es diuen Joan:
where $alumne/@aprovat="si" and $alumne/nom="Joan"
return $alumne/cognoms
<cognoms>Centelles</cognoms>
El where afegeix més potència del que sembla, ja que ens permet fer els inner joins d’SQL en fitxers XML. Per exemple, a partir de dos fitxers amb les dades de dues classes diferents es poden obtenir només els alumnes que es repeteixen entre les dues classes amb:
Atenció
L'anterior només és un exemple que no funcionarà, ja que no disposem del document classe2.xml
ORDER BY
Una de les operacions habituals en les cerques és representar els resultats en un ordre determinat. Aquesta és la funció que fa order by.
Es pot ordenar de manera ascendent amb ascending (que és el que fa per defecte) o bé descendent amb descending.
<alumne delegat="si" aprovat="si">
<nom>Joan</nom>
<cognoms>Centelles</cognoms>
<nota>8</nota>
</alumne>
<alumne aprovat="no">
<nom>Bernat</nom>
<cognoms>Balaguer</cognoms>
<nota>3</nota>
</alumne>
<alumne aprovat="si">
<nom>Albert</nom>
<cognoms>Alegre</cognoms>
<nota>6</nota>
</alumne>
També es poden especificar diferents conceptes en l’ordenació. En aquest exemple els resultats s’ordenaran primer per cognom i després per nom:
En aquest altre el cognom s’ordena de manera descendent i el nom de manera ascendent.
Per defecte ordena com si el contingut de les etiquetes fóra text. Si hem d'obtenir una ordenació numèrica, caldrà convertir els valors a números amb la funció d’XPath number().
La Magdalena --> 84
Pujada a Penyagolosa --> 530
Catí - Sant Pere de Castellfort --> 1286
Pelegrins de Les Useres --> 1738
Llicenciat sota la Llicència Creative Commons Reconeixement SenseObraDerivada 4.0