Hans-Jurgen,
Thank you for your detailed help. This really helped me to understand
what I was doing (as opposed to what I was trying to do).
Based on your detailed comments and the following usage notes on
fold-left from Priscilla Walmsley's XQuery book
"This function performs an operation (the function $f ) on two items
at a time, accu‐
mulating a result as it goes. It first calls the function using
$zero as the first argument
and the first item in $seq as the second argument. It then calls it
a second time using
the result of the previous function call as the first argument, and
the second item in
$seq as the second argument. It continues until there are no further
items in $seq ."
I figured out that I reversed the two parameters in the function call,
and based on that also reversed the ordering in the first argument of
the fold-left. The following (note the reversal of arguments in
local:stand-totaal($obj, $stand) and in the first argument of
`fold-left`) gives me the desired result:
```
let $stand1 := fold-left(($obj1, $obj2) , (), function($stand, $obj)
{ local:stand-totaal($obj, $stand) })
let $stand2 := fold-left(($obj2, $obj3) , (), function($stand, $obj)
{ local:stand-totaal($obj, $stand) })
let $stand3 := fold-left(($obj1, $obj2, $obj3) , (),
function($stand, $obj) { local:stand-totaal($obj, $stand) })
return ( '1 <-> 2 ==================', $stand1,
'2 <-> 3 ==================', $stand2,
'1 <-> 2 <-> 3 ============', $stand3
)
```
>From your expectations I gather that you want to exclude later reuse
of an ID possessed by an object with status "beeindigen". Therefore I
suggest the following simple solution of the problem:
Actually, that is not the case. Later reuse must be possible.
Thank you all for the help, MArco
On 19-12-2023 11:23, Hans-Juergen Rennau wrote:
Hi Marco,
I've also taken a look at the code and I think the observed behaviour
is in accordance with the logic of the accumulator function
(local:stand-totaal), while this logic is probably not really what.
First - why do you get the result which you get?
(1) The logic of local:stand-totaal
(a) Accept the new item only if its ID is not found among the
accumulated items (before filtering these for the status, see b))
(b) Retain only those accumulated items which do not have a certain status
The input sequence is objects 3, 2, 1
(1) Process object 3: Object accepted, as the accumulator is still
empty, so the object ID is "new"; the fact that the new object has a
<status> element is ignored.
(2) Process object 2: The object is rejected, as its ID is found in
the accumulator; the accumulator is then filtered, discarding object 3
because of its status; result: the accumulator is again empty (nothing
added, and what was there has been removed)
(3) Process object 1: The object is accepted, as the accumulator is
again empty, so the item ID is "new"
From your expectations I gather that you want to exclude later reuse
of an ID possessed by an object with status "beeindigen". Therefore I
suggest the following simple solution of the problem:
(a) Extract all IDs of an object with that status
(b) Before fold-left, filter the sequence of objects, discarding any
object with such an ID
(c) Process the filtered sequence, not thinking about the status any
more, just checking the ID
This processing is best encapsulated in a function (e.g. update-stand()).
With kind regards,
Hans-Jürgen
PS: Code snippet for the suggestion:
declare function local:update-stand($objects as element()*)
as element()* {
let $idsIGN := $objects[.//*:status =
'beëindigen']//*:identificatie => distinct-values()
let $objectsF := $objects[not(.//*:identificatie = $idsIGN)]
return fold-left($objectsF, (), local:stand-totaal#2)
};
declare function local:stand-totaal
(: returns an object by comparing new to old :)
(: newest should be returned, except when
<ow:status>beëindigen</ow:status>
then no object should be returned :)
($new as item()*,
$old as item()*) as item()* {
let $new_ids := $new//*:identificatie => distinct-values()
return ($new, $old[not(.//*:identificatie = $new_ids)])
};
Am Dienstag, 19. Dezember 2023 um 10:38:49 MEZ hat Martin Honnen
<martin.hon...@gmx.de> Folgendes geschrieben:
On 19/12/2023 09:53, Marco Duiker - LandGoed wrote:
Please help me with the following problem:
I try to construct the current status of a series of objects along
the following simple rules:
* the current status of on object with a certain `identificatie`
(id) is the newest version of that object
* except when the newest object has the property
`<status>beëindigen</status>` then the object stops existing.
I use a fold-left to proces these rules with a simple function
implementing those rules. This gives me unexpected results.
I've reduced the problem to a single stand alone query in which the
last object (`obj3`) has the property `<status>beëindigen</status>`.
So I would expect this line:
`let $stand4 := fold-left(($obj3, $obj2, $obj1), (), function($stand,
$obj) { local:stand-totaal($stand, $obj) })`
to give me an empty result as `obj3`has the property
<status>beëindigen</status>
but I am getting `obj1` as demonstrated in the following stand alone
query.
When running the stand alone query I would *expect*:
declare function local:stand-totaal
(: returns an object by comparing new to old :)
(: newest should be returned, except when
<ow:status>beëindigen</ow:status>
then no object should be returned :)
($new as item()*,
$old as item()*) as item()* {
let $new_ids := local:id($new)
let $stand_deel1 :=
for $obj_oud in $old//*:owObject
where not(local:id($obj_oud) = $new_ids)
return <sl:stand>{ $obj_oud }</sl:stand>
let $stand_deel2 :=
for $obj_new in $new//*:owObject[not(.//*:status)]
return <sl:stand>{ $obj_new }</sl:stand>
return ($stand_deel1, $stand_deel2)
};
From your comment and explanation I kind of would expect a check for
that particular value
<ow:status>beëindigen</ow:status>
but that value is not checked for or mentioned at all in the XQuery code.
--
Marco Duiker
LandGoed
Technisch directeur
+31617115114