Как избежать повторного объявления транзакций в Xquery

Данный:

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);

Как мне избежать повторного объявления $name?


person Ben Aston    schedule 07.08.2013    source источник
comment
Какой процессор XQuery вы используете? Должна ли $name быть переменной?   -  person wst    schedule 07.08.2013
comment
МаркЛогик 6 (XQuery 3). Для целей примера я хотел бы, чтобы $name была переменной.   -  person Ben Aston    schedule 07.08.2013


Ответы (2)


Используя отдельные транзакции, я не уверен, что есть хороший способ сделать это. Но вы можете объявить свою переменную внешней. Его все равно придется объявлять несколько раз, но вам нужно будет назначить только один раз при вызове через xdmp:invoke (или 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);

Затем вы можете вызывать этот модуль несколько раз, используя invoke с разными значениями:

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'))

Если вам не нужен дополнительный модуль, вы можете поместить его в функцию, которая принимает параметр $name и использует вместо него xdmp:eval.

person wst    schedule 07.08.2013
comment
Спасибо. Есть ли способ выполнить мой пример за одну транзакцию? - person Ben Aston; 07.08.2013
comment
Да, но из точки с запятой в вашем примере я предположил, что вы используете несколько транзакций. Вы можете использовать транзакции с несколькими операторами (новое в ML6), которые будут выполнять несколько транзакций и фиксировать их все атомарно. Или, если вы не получаете конфликтующие обновления от последовательных xdmp:node-delete, просто объявите $name один раз и не используйте точку с запятой. - person wst; 07.08.2013

В одной транзакции есть более простые способы, но это должно работать (не проверено)

let $name := '751-1500'     
let $doc := doc(concat('/', $name, '.xml'))
return 
(xdmp:node-delete($doc//foo),
 xdmp:node-delete($doc//bar),
 xdmp:node-delete($doc//baz))
person Eric Bloch    schedule 07.08.2013