Domanda

I have extracted successfully one value in one variable, and a list of values in another variable (as part of my XQuery expression).

Now, suppose the single-value variable is

x=1

and the list variable is named y with values 2,4,7,11,16

I want to extract the following values -- (2-1), (4-2), (7-4), (11-7), (16-11)

ie, first value of list variable minus single value variable, then differences between successive members of the list variable.

I tried using

for $pos in list-variable/position() 
-> if clause for $pos=1 (to subtract and shown list variable- single value variable)    
->else show difference b/w consecutive list variables... 

but nothing is shown at all as output... What am I doing wrong here?

È stato utile?

Soluzione

I. With XQuery 3.0 / Xpath 3.0, use:

let $pVal := 1,
    $vList := (2,4,7,11,16),
    $vList2 := ($pVal, subsequence($vList, 1, count($vList)-1))
 return
    map-pairs(function($m as xs:integer, $n as xs:integer) as xs:integer
                {
                 $m - $n
                },
                $vList,
                $vList2
              )

This produces the wanted, correct result:

1 2 3 4 5

II. XQuery 1.0 solution:

let $pVal := 1,
    $vList := (2,4,7,11,16),
    $vList2 := ($pVal, subsequence($vList, 1, count($vList)-1))
 return
    for $i in 1 to count($vList)
     return
        $vList[$i] - $vList2[$i]

again produces the same correct result:

1 2 3 4 5

Performance comparison:

Surprizingly, the XPath (XQuery) 3.0 query is executed almost twice faster than the XQuery 1.0 one -- when run on BaseX.

Altri suggerimenti

Your example is so abstract, it is really not clear what you tried to use.

But you can subtract $x or the previous element like this:

 let $x := 1, $seq := (2,4,7,11,16)  
 for $temp at $pos in $seq 
 return $seq[$pos] - if ($pos eq 1) then $x else $seq[$pos - 1]

Remember to use 'at $pos' if you want the position.

(And btw, XQuery 3 also has the window clause just for this case:

Would probably look like this:

 let $x := 1, $seq := (2,4,7,11,16) 
 for sliding window $w in ($x, $seq)
     start at $s when fn:true()
     only end at $e when $e - $s eq 1
 return $w[2] - $w[1]

does not appear to be easier, but it is cooler)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top