Обновление XQuery: вставить или заменить в зависимости от того, существует ли узел, если это невозможно?
Я пытаюсь создать простую базу данных XML (внутри BaseX или eXist-db), но у меня возникают проблемы с выяснением того, как изменить значения в документе:
содержание просто для теста:
<p>
<pl>
<id>6></id>
</pl>
</p>
Я пытаюсь построить что-то вроде функции, которая вставила бы элемент в <pl>
если этот элемент отсутствует или замените его, если он присутствует. Но XQuery доставляет мне неприятности:
Когда я пробую это в лоб с логикой if-then-else:
if (exists(/p/pl[id=6]/name)=false)
then insert node <name>thenname</name> into /p/pl[id=6]
else replace value of node /p/pl[id=6]/name with 'elsename'
Я получаю ошибку Error: [XUDY0027] Replace target must not be empty
, Понятно, что я запутался, почему в обоих случаях вычисляется часть else, таким образом ошибка. Когда я освобождаю остальную часть:
if (exists(/p/pl[id=6]/name)=true)
then insert node <name>thenname</name> into /p/pl[id=6]
else <dummy/>
Тогда я получаю Error: [XUST0001] If expression: no updating expression allowed
,
Когда я пытаюсь объявить функцию обновления, даже тогда она сообщает об ошибке:
declare namespace testa='test';
declare updating function testa:bid($a, $b)
{
if (exists(/p/pl[id=6]/name)=true)
then insert node <name>thenname</name> into /p/pl[id=6]
else <dummy/>
};
testa:bid(0,0)
Error: [XUST0001] If expression: no updating expression allowed.
Я получил эти ошибки из пакета BaseX 6.5.1.
Итак, как я могу изменить значения простым способом, если это возможно? Если я вызову вставку прямо, то может быть несколько элементов одинакового значения. Если я позвоню заменить, он не будет работать, когда узел не существует. Если я удаляю узел перед вставкой / заменой, я могу уничтожить подузлы, которые мне не нужны.
В большинстве баз данных SQL это довольно простая задача (например, команда MYSQL 'replace').
1 ответ
@Qiqi: @ Алехандро прав. Ваше выражение if имеет неверный синтаксис XQuery:
if (exists(/p/pl[id=6]/name))
then insert node <name>thenname</name> into /p/pl[id=6]
else replace value of node /p/pl[id=6]/name with 'elsename'
Обратите внимание, что функциональность XXuery Update в eXist-db в настоящее время является реализацией, специфичной для eXist, поэтому в eXist (в настоящее время) 1.4.x и 1.5dev вам понадобится:
if (exists(/p/pl[id=6]/name))
then update insert <name>thenname</name> into /p/pl[id=6]
else update value /p/pl[id=6]/name with 'elsename'
Этот специфичный для eXist синтаксис XQuery Update задокументирован по http://exist-db.org/update_ext.html. Этот синтаксис был разработан до того, как спецификация W3C XQuery Update достигла текущего состояния. Команда eXist планирует в ближайшее время сделать eXist полностью совместимым со спецификацией W3C, но в то же время приведенные выше документы должны помочь вам достичь того, что вам нужно, если вы используете eXist.
Обратите внимание, что ваш пример кода содержит опечатку внутри элементов pl и id. Действительная версия XML будет:
<p>
<pl>
<id>6</id>
</pl>
</p>