обратная операция должна удалять последнего
Следовательно, обратная операция должна удалять последнего ребенка целевого узла. Например, для операции вставки InsertInto(<name/>, /doc/person) в столбец Parameters нужно записать информацию об операции Delete/doc/person/name[position() =last()]. При выполнении UNDO необходимо выполнить эту операцию удаления.
Пусть opi - это операция IB. Аналогично, в столбец Parameters нужно записать информацию об операции удаления вставленного узла. Например, для операции вставки InsertBefore(<name/>, /doc/person/hobby) в столбец Patrameters необходимо записать информацию об операции Delete(/doc/person/hobby::preceding-sibling [ position()=1]). Для операции IA в последнем выражении необходимо заменить ось preceding-sibling на following-sibling. Пусть opi - это операция D. Для операции удаления узла обратной является операция вставки этого узла. Поэтому удаляемый узел необходимо сохранить в журнале, чтобы при откате можно было его вставить. При этом требуется запомнить не только сам удаляемый узел, но и его позицию в XML-документе. Для этого перед выполнением операции удаления нужно выполнить предварительный запрос, результатом которого будут удаляемые узлы и их позиции в XML-документе. Например, для операции Delete(/doc/person[name='John']) предварительный запрос будет выглядеть так:
for $node at $i in /doc/person where $node/name = 'John' return ($node, $i)
Этот запрос выбирает все узлы person с именем "John", а также их позиции среди всех узлов person. Результат запроса сохраняется в столбце Parameters таблицы журнала. Кроме того, сохраняется путь в XML-документе, по которому нужно будет вставлять узлы при выполнении отката. Для рассматриваемого примера таким путем является /doc.
При выполнении обратной операции (UNDO) выполняются следующие действия:
Содержание Назад Вперед