Gern stehe ich zur fachlichen Unterstützung in XML-Technologien, C#.NET, VisualBasic.NET und Java zur Verfügung. Sprechen Sie mich einfach an: Mail oder ☎ 0151 . 750 360 61


XPath 3.0, XPath 2.0, XPath 1.0 / XPath-Funktionen / XPath: Sequenz-Funktionen / XPath: fold-left

XPath: fold-left

XPath: fold-left

➪ Die XPath-Funktion fold-left verarbeitet alle Items einer Sequenz von links nach rechts. Sie eignet sich damit gut für erweiterte Zahlenfunktionen, etwa bei Kumulierungen oder Multiplikationen.

Auf dieser Seite:

Siehe auch .

Sequenzen multiplizieren

Während die -Funktion Zahlenwerte addieren kann, gibt es kein Standardverfahren für die Multiplikation. Hier kann fold-left gute Hilfe bieten. Der folgende Aufruf multipliziert alle Werte von 1 bis 5.


let $input := (1 to 5)
return element {'ergebnis'}{ 
    fold-left( 
               $input, 
               1, 
               function($a, $b){
                  $a * $b                        
               }
    )        
}

Das Ergebnis ist unschwer nachvollziehbar:


<ergebnis>120</ergebnis>

Sie haben auch Null-Werte in der Sequenz und möchten diese ignorieren? Kein Problem:


let $input := (1 to 5, 0)
return element {'ergebnis'}{ 
    fold-left( 
               $input[. != 0], 
               1, 
               function($a, $b){
                  $a * $b                        
               }
    )        
}

Sequenzen kumulieren

Ähnlich wie viele andere (, , u.a.m) liefert die soeben beschriebene Multiplikation nur einen Einzelwert zurück. Wenn Sie jedoch die Zwischenwerte ebenfalls benötigen, etwa bei Kumulierungen, können Sie so vorgehen:


element {'ergebnis'}{ 
    for $w in (1 to 10) return element {'value'}{
        attribute {'i'}{$w},
        attribute {'kumuliert'}{
            fold-left(
                   (  1 to (xs:int($w))  ), 
                   0, 
                   function($a, $b){
                        $a + $b                        
                    }
              )
        },
        attribute {'multipliziert'}{
            fold-left(
                   (  1 to (xs:int($w))  ), 
                   1, 
                   function($a, $b){
                        $a * $b                        
                    }
              )
        }
    }    
 }

Im vorliegenden Fall können Sie analog mit arbeiten: Das Resultat ist unverändert:


<ergebnis>
   <value i="1"  kumuliert="1"  multipliziert="1"/>
   <value i="2"  kumuliert="3"  multipliziert="2"/>
   <value i="3"  kumuliert="6"  multipliziert="6"/>
   <value i="4"  kumuliert="10" multipliziert="24"/>
   <value i="5"  kumuliert="15" multipliziert="120"/>
   <value i="6"  kumuliert="21" multipliziert="720"/>
   <value i="7"  kumuliert="28" multipliziert="5040"/>
   <value i="8"  kumuliert="36" multipliziert="40320"/>
   <value i="9"  kumuliert="45" multipliziert="362880"/>
   <value i="10" kumuliert="55" multipliziert="3628800"/>
</ergebnis

Siehe auch und .

fold-left

Die XPath-Funktion fold-left fordert drei Parameter ein: zwei Sequenzen sowie eine Funktion, mit der das Ergebnis berechnet wird. Der folgende Aufruf definiert zwei Sequenzen sowie deren Verkettung (Komma!) in einer Funktion.


<xsl:template match="/">
  <root>
   <xsl:for-each 
        select="fn:fold-left(
                   (5 to 10), 
                   (15 to 20), 
                   function($a, $b){$a, $b})">
    <wert>
     <xsl:value-of select="."/>
    </wert>
   </xsl:for-each>
  </root>
</xsl:template>

Bemerkenswert ist hierbei, dass die zweite Sequenz zuerst betrachtet wird:


<root>
  <wert>15</wert>
  <wert>16</wert>
  <wert>17</wert>
  <wert>18</wert>
  <wert>19</wert>
  <wert>20</wert>
  <wert>5</wert>
  <wert>6</wert>
  <wert>7</wert>
  <wert>8</wert>
  <wert>9</wert>
  <wert>10</wert>
</root>

Das zweite Beispiel multipliziert die Einzelwerte der Reihe 6 * 1 * 2 * 3 miteinander:


<xsl:template match="/">
  <root>
   <xsl:for-each 
        select="fn:fold-left(
                   (1 to 3), 
                   6, 
                   function($a, $b){$a * $b})">
    <wert>
     <xsl:value-of select="."/>
    </wert>
   </xsl:for-each>
  </root>
</xsl:template>

... und kommt auf ein nachvollziehbares Ergebnis:


<root>
  <wert>36</wert>
</root>

Auch andere bewährte Funktionen können eingebunden werden, etwa concat:


<xsl:template match="/">
  <root>
   <xsl:for-each 
        select="fn:fold-left(
                   1 to 5, 
                   'Sprachlos', 
                   fn:concat(?, ' | ', ?))">
    <wert>
     <xsl:value-of select="."/>
    </wert>
   </xsl:for-each>
  </root>
</xsl:template>

Das erzielte Ergebnis sieht dann so aus:


<root>
  <wert>Sprachlos | 1 | 2 | 3 | 4 | 5</wert>
</root>

wg / 1. Mai 2019



Fragen? Anmerkungen? Tipps?

Bitte nehmen Sie Kontakt zu mir auf.






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/foldleft.html