My XML document contains a record of the movement of an object. The XML document consists of a series of observations. Each observation contains the lat/long location of the object, the lat/long of the observing sensor, and a date/time stamp.
<Track-History>
<Track-ID>XYZ</Track-ID>
<Observation>
<Target-Latitude>10.3</Target-Latitude>
<Target-Longitude>20.8</Target-Longitude>
<Observer-Latitude>40.0</Observer-Latitude>
<Observer-Longitude>50.0</Observer-Longitude>
<DateTime>20230202T071700.00</DateTime>
</Observation>
<Observation>
<Target-Latitude>15.1</Target-Latitude>
<Target-Longitude>25.2</Target-Longitude>
<Observer-Latitude>40.0</Observer-Latitude>
<Observer-Longitude>50.0</Observer-Longitude>
<DateTime>20230202T071800.00</DateTime>
</Observation>
</Track-History>
I want to fuzz the locations of the object by rounding the decimal lat and long values. So I created this updating function:
declare updating function f:fuzzPoint($lat as element(), $long as element())
{
replace node $lat with
element {name($lat)} {round(number(data($lat)))},
replace node $long with
element {name($long)} {round(number(data($long)))}
};
When I invoke that function:
{f:fuzzPoint($obs/Target-Latitude, $obs/Target-Longitude)}
I get this error message:
If any subexpression is updating, then all must be updating
Oxygen XML gives a red squiggly line under the function arguments, so apparently the arguments must be updating. Yes? If so, how to make the arguments updating?
Below is my complete XQuery Update program.
declare namespace f = "function";
declare variable $Track-History := doc('Track-History.xml');
declare variable $track-history-points := (for $i in $Track-History//Observation return [$i/Target-Latitude, $i/Target-Longitude]);
declare variable $AOR := (); (: should be a sequence of points, fake it for now :)
declare function f:isInside($points, $polygon) as xs:boolean
{
true()
};
declare updating function f:fuzzPoint($lat as element(), $long as element())
{
replace node $lat with
element {name($lat)} {round(number(data($lat)))},
replace node $long with
element {name($long)} {round(number(data($long)))}
};
if (f:isInside($track-history-points, $AOR)) then
for $obs in $Track-History//Observation return
replace node $obs with
<Observation>
{f:fuzzPoint($obs/Target-Latitude, $obs/Target-Longitude)}
{$obs/Observer-Latitude}
{$obs/Observer-Longitude}
{$obs/DateTime}
</Observation>
else
replace node $Track-History/* with
<Track-History/>