Wenn eine Funktion auf einer Kontenmenge operiert, dann kann der Funktionsaufruf auch an einen Pfadselektor gehangen werden, bspw. so:
<xsl:value-of select="sum($current/betrag[xs:decimal(.) gt 0]/xs:decimal(.))"/>Plain Text
Hier werden die betrag -Knoten eines zuvor selektierten Teilbaums, der in der Variablen $current abgespeichert ist, aufsummiert - aber nur wenn der Wert größer als 0 ist.
Der Funktionsaufruf ist hier ein Type-Cast auf einen Dezimalwert, um eine gewisse Rechengenauigkeit zu gewährleisten.
Die Filterung auf positive Werte ist dabei noch gewöhnlich formuliert:
[xs:decimal(.) gt 0]Plain Textxs:decimal nimmt den aktuell ausgwählten Knoten und macht einen Dezimalwert daraus, um ihn mit 0 zu vergleichen.
Falls hier an den Typkonstruktor xs:decimal ein nicht-unterstütztes Format übergeben wird, bspw. ein String, dann wird ein fatalen Fehler geworfen und das Programm bricht ab.
Der Funktionsaufruf kann aber auch als Pfadselektion an einem XPath angebracht werden:
/xs:decimal(.)Plain TextIm Fehlerfall wird der fehlerhafte Wert nicht summiert und das Programm läuft weiter.
$current/betrag[xs:decimal(.) gt 0]Plain Text
Auf herkömmlichen Weg würde man eine Schleife verwenden, die alle Werte auf deren Dezimalwert abbildet:
sum(for $x in $current/betrag[xs:decimal(.) gt 0] return xs:decimal($x))Plain Text
Das ist ein bisschen komplizerter, gewährleistet aber eine bessere Robustheit der Programmierung.
Betrachten wir folgendes XQuery-Schnippsel:
collection("/abrechnung")[vorgangsnummer[.=(3, 8,9,10)]/xdmp:node-collections(.)
[starts-with(., '/buchung')]/xdmp:collection-delete(.)Plain TextHier sind alle Abrechnungen in einer Collection /abrechnung gespeichert. Die Abrechungen mit den Vorgangsnummern 3,8,9 und 10 sollen herausgefischt werden. Diese Abrechungen können auch in verschiedenen Collections verwaltet werden, bspw. mittels eines Collection-Typs "Buchung". Eine Buchung-Collection sammelt alle Abrechungen, die an einem bestimmten Buchungstag getätigt wurden. Wir gehen jetzt davon aus, dass alle Abrechungen 3,8,9,10 an einem bestimmten Buchungstag getätigt wurden - und nur diese. Aus irgendeinem Grund wollen wir diese Buchung nun löschen. Das macht genau der obige Einzeiler. Der Filter:
collection("/abrechnung")[vorgangsnummer[.=(3, 8,9,10)]Plain Textgibt eine Knotenmenge zurück. Das gefilterte Funktionsergebnis
xdmp:node-collections(.)[starts-with(., '/buchung')]Plain Textist auch eine Knotenmenge. Normalerweise bräuchten wir also Schleifen, um über diese Mengen zu iterieren. Das würde irgendwie so aussehen
let $filtered-collection := collection("/abrechnung")[vorgangsnummer[.=(3, 8,9,10)], $collections-to-be-deleted := distinct-values( for $x in $collection return ( for $y in xdmp:document-get-collections(fn:document-uri($x)) [starts-with(., '/buchung')] return $y ) ) return ( for $culprit in $collections-to-be-deleted return xdmp:collection-delete($culprit) )Plain Text
Der Quelltext ist zwar so wesentlich länger, aber auch weniger geübte XPath-Experten erkennen leicht, um was es geht.