Dear all, I just started learning XQuery. I have the following XML:
<Keywords> <Record Keywords="Bus"> 10 20 30 40</Record> <Record Keywords="Bus"> 11 21 31 41</Record> </Keywords>
I'm using the following script to multiply by 2 values 30 and 31.
for $v in /Keywords/Record let $v1 := xs:float($v/tokenize(.,"[|]| ")[3]) return replace value of node $v with replace ($v, $v/tokenize(.,"[|]| ")[3], xs:string($v1 * 2))
The output is correct (please tell me if my script is ok or if there are better ways to accomplish the same task).
<Keywords> <Record Keywords="Bus">10 20 60 40</Record> <Record Keywords="Bus">11 21 62 41</Record> </Keywords>
Now I would like to perform a similar operation but: case 1) applying the same operation on multiple elements (i.e. element 3 and 4) case 2) applying the same operation on all element (i.e. 1,2,3,4)
For case 2) I tried the following (just removing the index [3])
for $v in /Keywords/Record let $v1 := xs:float($v/tokenize(.,"[|]| ")) return replace value of node $v with replace ($v, $v/tokenize(.,"[|]| "), xs:string($v1 * 2))
But I get the error: Item expected, sequence found: ("10", "20", "...") I also tried to write a script with two nested for loops, but unsuccessfully.
Can you help me?
Hi Marco,
case 2) applying the same operation on all element (i.e. 1,2,3,4)
Here is one solution (I bound your document to the context item and used the 'update' keyword, such that the effects of the main-memory updates will be immediately visible):
declare context item := document { <Keywords> <Record Keywords="Bus">10 20 30 40</Record> <Record Keywords="Bus">11 21 31 41</Record> </Keywords> }; . update { for $record in /Keywords/Record let $values := tokenize($record) let $updated-numbers := ( for $value in $values return number($value) * 2 ) let $new-value := string-join($updated-numbers, ' ') return replace value of node $record with $new-value }
case 1) applying the same operation on multiple elements (i.e. element 3 and 4)
I added the solution for Case 1 after the first, as it can be treated as a special-case. Moreover, I varied the user XQuery expressions a little, simply to show that there are various other solutions:
. update { for $record-text in /Keywords/Record/text() return replace node $record-text with ( for $value at $pos in tokenize($record-text) return if($pos = (3,4)) then number($value) * 2 else $value ) => string-join(' ') }
Hope this helps, Christian
basex-talk@mailman.uni-konstanz.de