Was ist XQuery? / XQuery: WHERE und Numerierung

XQuery: WHERE und Numerierung

XQuery: WHERE und Numerierung

➪ Die WHERE-Klausel filtert aus der Liste jener Nodes, die im vorhergehenden XPath-Statement angesprochen werden, jene heraus, die den WHERE-Kriterien entsprechen. Sollen die gefundenen Nodes in der Ausgabe numeriert werden, kann die WHERE-Klausel kontraproduktiv sein.

Bereits vorhin haben wir uns einen XQuery-Loop der Art "for $y at $p in <sequence>" angesehen, wo $y das jeweilige Item repräsentierte und $p dessen Position in der Sequence. Hier noch einmal ein Beispiel für den späteren Vergleich:


<erg>
{
for $m at $p in /Orte/Ort[1]/Mensch
return 
<m p="{$p}" id="{$m/id}">
  {$m/vorname/text()}
</m>
}
</erg>

Das Ergebnis ist eine Nodeliste, dessen Attribut "p" die jeweilige Position darstellt; das Attribut "id" repräsentiert den Elementinhalt aus dem Quelldokument. So weit, so gut:


<erg>
  <m p="1" id="1">Hugo</m>
  <m p="2" id="4">Nicole</m>
  <m p="3" id="9">Stefan</m>
  <m p="4" id="2">Stefan</m>
  <m p="5" id="3">Siggi</m>
  <m p="6" id="7">Heini</m>
</erg>

Nun ändern wie die XQuery-Logik: nach dem "for $m at $p in /Orte/Ort[1]/Mensch"-Loop fügen wir die Einschränkung "where $m/id/text() > 2" ein.


<erg>
{
for $m at $p in /Orte/Ort[1]/Mensch
where $m/id/text() > 2
return 
<m p="{$p}" id="{$m/id}">
  {$m/vorname/text()}
</m>
}
</erg>

Das Ergebnis ist wie gewünscht: es werden nur Items mit einer "id" größer als 2 ausgegeben: "3, 9, 4, 7". Aber halt, da stimmt doch was nicht! Was ist mit der Numerierung im Attribut "p"? Die Reihenfolge "2, 3, 5, 6" ist (genau genommen) etwas lückenhaft. Es sieht so aus, als würde der "for $m at $p in /Orte/Ort[1]/Mensch"-Loop im Speicher die ursprüngliche Reihenfolge komplett generieren und anschließend mit der "where"-Einschränkung aus dieser Reihenfolge jene Elemente löschen, die der Einschränkung unterliegen.


<erg>
  <m p="2" id="4">Nicole</m>
  <m p="3" id="9">Stefan</m>
  <m p="5" id="3">Siggi</m>
  <m p="6" id="7">Heini</m>
</erg>

In XSL-Syntax wäre der Effekt derselbe, wenn wir die folgende Logik implementiert hätten:


 <erg>
  <xsl:for-each select="/Orte/Ort[1]/Mensch">
   <xsl:if test="id &gt; 2">
    <m p="{position()}" id="{id}">
     <xsl:value-of select="vorname" />
    </m>
   </xsl:if>
  </xsl:for-each>
 </erg>

Wie kommen wir nun zur korrekten Numerierung? Recht einfach: wir müssen mit einem paßgenauen XPath-Statement dafür sorgen, daß von vornherein nur die relevanten Nodes in der Sequence auftauchen. Dann paßt die Numerierung sofort, und die "WHERE"-Einschränkung entfällt.


<erg>
{
for $m at $p in /Orte/Ort[1]/Mensch[id > 2]
return 
<m p="{$p}" id="{$m/id}">
  {$m/vorname/text()}
</m>
}
</erg>

In XSL ist das Vorgehen analog: präzise Arbeit mit XPath.


 <erg>
  <xsl:for-each 
       select="/Orte/Ort[1]/Mensch[id &gt; 2]">
   <m p="{position()}" id="{id}">
    <xsl:value-of select="vorname" />
   </m>
  </xsl:for-each>
 </erg>

Und dann stimmts auch mit der Numerierung:


<erg>
  <m p="1" id="4">Nicole</m>
  <m p="2" id="9">Stefan</m>
  <m p="3" id="3">Siggi</m>
  <m p="4" id="7">Heini</m>
</erg>

Aus diesem Grunde empfehle ich eine präzise Arbeit mt XPath-Statements, auch dann, wenn es nicht um Numerierung geht.

wg / 22. März 2018



Fragen? Anmerkungen? Tips?

Bitte nehmen Sie Kontakt zu mir auf:

Vorname
Nachname
Mailadresse







Vielen Dank für Ihr Interesse an meiner Arbeit.


V.i.S.d.P.: Wilfried Grupe * Klus 6 * 37643 Negenborn

☎ 0151. 750 360 61 * eMail: info10@wilfried-grupe.de

www.wilfried-grupe.de/XQuery7.html