Обновление 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>
Другие вопросы по тегам