Search code examples
transactionsxquerymarklogic

Avoiding redeclaration for transactions in Xquery


Given:

let $name := '751-1500'    
return xdmp:node-delete(doc(concat('/', $name, '.xml'))//foo);

let $name := '751-1500'
return xdmp:node-delete(doc(concat('/', $name, '.xml'))//bar);

let $name := '751-1500'
return xdmp:node-delete(doc(concat('/', $name, '.xml'))//baz);

How can I avoid having to redeclare $name?


Solution

  • Using separate transactions I'm not sure there is a nice way to do this. But you can declare your variable as external. It will still have to be declared multiple times, but you will only have to assign once when called via xdmp:invoke (or xdmp:eval):

    declare variable $name as xs:string external ;
    xdmp:node-delete(doc(concat('/', $name, '.xml'))//foo);
    
    declare variable $name as xs:string external ;    
    xdmp:node-delete(doc(concat('/', $name, '.xml'))//bar);
    
    declare variable $name as xs:string external ;
    xdmp:node-delete(doc(concat('/', $name, '.xml'))//baz);
    

    Then you can call this module multiple times using invoke with different values:

    xdmp:invoke('delete-nodes.xqy', (xs:QName('name'), '751-1500')),
    xdmp:invoke('delete-nodes.xqy', (xs:QName('name'), '751-1501')),
    xdmp:invoke('delete-nodes.xqy', (xs:QName('name'), '751-1502'))
    

    If you don't want the extra module, you could wrap it all in a function that accepts the $name param and uses xdmp:eval instead.