Home
Über mich
Blog
Veröffentlichungen
IT-Trainings
Impressum


WHERE und Numerierung

Bereits vorhin haben wir uns einen 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.

qrpic/XQuery7.jpg

wg / 14. Oktober 2017




Fragen? Anmerkungen? Tips?

Bitte nehmen Sie Kontakt zu mir auf (info10@wilfried-grupe.de).



Vielen Dank für Ihr Interesse an meiner Arbeit.


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

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