Запросы XQuery Update в BaseX выполняются успешно, но в файл не записываются никакие изменения.

Я пытаюсь использовать XQuery и BaseX для управления некоторыми файлами files.xml как базами данных.

Я использую basexclient для отправки запросов на basexserver. Например, у меня есть простой файл с именем library.xml, подобный следующему:

<library>
   <book>gone with the wind</book>
   <book>the thornbirds</book>
</library>

и я хотел бы добавить узел, поэтому с basexclient терминала я отправляю:

XQUERY insert node <book>Dracula</book> as last into doc('library.xml')//library

а потом я получаю сообщение

Запрос выполняется за 10,5 мс

Но в файле ничего не изменилось. Есть ли команда для фиксации изменений?


person SagittariusA    schedule 05.12.2014    source источник
comment
Вы проверяете исходный файл или базу данных, созданную из него? Если вы создали базу данных, изменения не записываются в файл автоматически. doc('library.xml') содержит ли изменения?   -  person Jens Erat    schedule 05.12.2014
comment
Да, я проверяю исходный файл, и он не содержит никаких изменений. Я несколько дней читал документацию по Basex, но до сих пор не понял, как это работает.   -  person SagittariusA    schedule 05.12.2014
comment
Я добавил запрос функции, чтобы напечатать предупреждающее сообщение в таких случаях. В этом случае BaseX действительно не дружелюбен (особенно) для новых пользователей.   -  person Jens Erat    schedule 05.12.2014


Ответы (3)


Выполнение обновлений (сериализованных) файлов XML практически невозможно. BaseX, а также другие базы данных XML на рынке используют специальные внутренние представления с индексами для быстрого запросы, и особенно обновления.

Если вы уже создали базу данных из файла, ваш запрос обновляет базу данных, а не исходный XML-файл. Вы должны иметь возможность наблюдать изменения (возможно, несколько раз, один узел добавляется для каждой попытки выполнить запрос) в представлении базы данных, что вы можете проверить, запустив

doc('library.xml')

и проверка его содержимого. Чтобы сериализовать изменения в файл, используйте EXPORT команду BaseX.

Если вы еще не создали базу данных и запросили файл на жестком диске, создается временная база данных в памяти, которая действительно успешно обновляется, но мгновенно удаляется. Создайте базу данных перед запуском обновлений.

См. ответ Кристиана Грюна, в котором обсуждается параметр WRITEBACK, который позволяет обновлять файл без создания баз данных.

person Jens Erat    schedule 05.12.2014

По умолчанию обновления экземпляров вашего файла в памяти не передаются обратно на диск. Вы можете изменить это, включив параметр WRITEBACK. Я согласен, что поведение удивительное; он был введен для предотвращения случайного изменения пользователями локальных файлов.

Общее примечание: если вы хотите обновить локальные файлы, возможно, лучше использовать BaseX в автономном режиме. Если вы работаете с архитектурой клиент / сервер (т. Е. С basexclient, а не basex), сервер мог быть запущен из другого рабочего каталога, и он не сможет разрешить относительный путь в вашей функции doc ().

person Christian Grün    schedule 05.12.2014

Я пишу простую службу синхронизации между системой и baseX. У меня аналогичная проблема в том, что я выполняю несколько запросов с помощью PHP-клиента и делаю несколько запросов в одном или нескольких сеансах, которые успешно завершаются без отображения результатов, просматриваемых из baseX dba. Я открываю, выполняю, получаю результаты, если они есть, и закрываю каждый запрос. Если я выполняю каждый запрос отдельно, я получаю обновленный результат (после обновления) в dba. Я запускаю это как службу с портом 1894, открытым для localhost. Каждый запрос имеет общую форму

try {
$myXML22 = 'somegenerated xml' 
$filepathname = "mydoc/mydoc_doc22.xml";
$docID = "22";
$dbName = "myDB";
$input = 'let $xml := \''.$myXML22.'\' '.
         'return db:replace("'.$dbName.'","'.$filepathname.'",$xml)';
$query = $session->query($input);
$log .= "Updated/added $filepathname to basex db ".$dbName." \n";
} catch (Exception $e) {
  error_log("somemessage".$e->getMessage());
}

Вот лог службы.

  1. Db myDB существует в baseX
  2. Найдено 24 редакции mydoc в базе данных myDB в baseX
  3. Проверенный манифест существует в базе данных myDB в baseX
  4. Найдено 5 записей timeStamp в манифесте базы данных myDB в baseX
  5. Создан XML для doc22
  6. Проверено по ГСЧ для doc22
  7. Обновлен / добавлен myxml / mydoc_doc22.xml в basex db myDB
  8. Узел timeStamp для mydoc 22 добавлен в манифест для basex db myDB
person steve    schedule 07.04.2017
comment
Кажется, что-то связано с systemd на ubuntu 16.04. Есть ли у кого-нибудь работающий пример basex.service? - person steve; 07.04.2017