[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] Can fold-left process the attributes nodes of a stream
I am struggling to find a compact way to use XSLT 3 streaming and an accumulator to sum up the attribute values of certain elements,e.g. xsl:accumulator name="attribute-sums" as="map(xs:QName, xs:decimal)" initial-value="map{}" streamable="yes" to accumulate the sum of each attribute by the name of the attribute.
B fold-left(@*, $value, function($v, $a) { map:put($v, node-name($a), (map:get($v, node-name($a)), 0)[1] + xs:decimal($a)) }) seemed like a compact and elegant use of XPath 3.1 but using a dynamic inline function as the argument to fold-left doesn't seem to pass the streamability analysis. Then I tried to set up a user-defined function to be passed in as the third argument to fold-left, but somehow that approach doesn't seem to work either as a streamable stylesheet function needs to take the streamable nodes as the first parameter while the signature of the function $f of fold-left would make the attribute node the second parameter. So the only options I could think of is not passing the attribute nodes themselves to fold-left but rather an array or map of the name and value I need to store in the accumulator e.g. fold-left(@* ! [node-name(), xs:decimal(.)], $value, function($v, $anv) { map:put($v, $anv?1, (map:get($v, $anv?1), 0)[1] + $anv?2) }) or to abandon fold-left and use xsl:iterate in the accumulator rules B B <xsl:accumulator name="attribute-sums" as="map(xs:QName, xs:decimal)" initial-value="map{}" streamable="yes"> B B B B B B B <xsl:accumulator-rule match="Book"> B B B B B B B B B B B <xsl:iterate select="@*"> B B B B B B B B B B B B B B B <xsl:param name="accumulator-map" select="$value"/> B B B B B B B B B B B B B B B <xsl:on-completion select="$accumulator-map"/> B B B B B B B B B B B B B B B <xsl:next-iteration> B B B B B B B B B B B B B B B B B B B <xsl:with-param name="accumulator-map" B B B B B B B B B B B B B B B B B B B B B B B select="map:put($accumulator-map, node-name(), (map:get($accumulator-map, node-name()), 0)[1] + xs:decimal(.))"/> B B B B B B B B B B B B B B B </xsl:next-iteration> B B B B B B B B B B B </xsl:iterate> B B B B B B B </xsl:accumulator-rule> B B B </xsl:accumulator>
Any ideas or opinions whether I have missed an approach to use fold-left?
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|