Классика баз данных - статьи

       

Семантика функциональных update-выражений вида TRANSFORM REPLACE


Функциональное update-выражение вида transform replace возвращает модифицированную копию последовательности узлов, возвращаемую XPath-выражения locpath1, в которой каждый узел из последовательности, являющейся результатом вычисления XPath-выражением locpath2, заменяется на последовательность узлов, возвращаемую выражением expr.

Тонкости определения семантики связаны с вычислением выражения expr. Пусть результатом вычисления выражения locpath2 является последовательность узлов L2. В случае, когда вычисление выражения expr зависит от узлов из последовательности L2, возникают следующие альтернативы:

  1. вычислять выражение expr на узлах исходного документа;
  2. вычислять выражение expr на модифицированных копиях узлов документа.

Чтобы проиллюстрировать различия, рассмотрим следующий абстрактный пример. Пусть необходимо трансформировать XML-данные следующего вида:.

<root> <a> <a>text1</a> <b>text2</b> <a>text3</a> </a> </root>

Рассмотрим функциональное update-выражение, описывающее трансформацию данных, заключающуюся в переименовании всех XML-элементов a на b:

for $r in doc("some.xml")/root transform replace $a in $r//a with <b> { ($a/@*,$a/*) } </b>

В этом выражении expr($var2) представляет собой конструктор <b>{($a/@*, $a/*)}</b>. Если вычислять выражение на узлах оригинального документа, то представленное функциональное update-выражение вернет следующий результат:

<root> <b> <a>text1</a> <b>text2</b> <a>text3</a> </b> </root>

Если же вычислять выражение на модифицированных копиях узлов документа, то результат будет отражать рекурсивную семантику трансформации:

<root> <b> <b>text1</b> <b>text2</b> <b>text3</b> </b> </root>

Будем называть семантику вычисление функционального update-выражения с вычислением выражения expr на узлах оригинального документа прямой, а семантику с вычислением выражения expr на модифицированных копиях узлов документа - рекурсивной.




Для определения семантики функциональных update-выражений вида TRANSFORM INSERT и TRANSFORM DELETE выразим их через функциональные update-выражения вида TRANSFORM REPLACE, для которых семантика была определена выше.

В синтаксисе функциональных update-выражений вида TRANSFORM INSERT выражение expr($var1,$var2) определяет упорядоченную последовательность узлов, которые необходимо вставить. Для каждого целевого узла последовательности, возвращаемой выражением locpath2, результат вычисления выражения expr($var1,$var2) вставляется на позицию, определяемую ключевыми словами into, preceding и following. Если указано ключевое слово into, то узлы вставляются в начало последовательности дочерних узлов целевого узла. Если указано ключевое слово preceding, то узлы вставляются непосредственно перед каждым целевым узлом. В случае, если позиция определяется ключевым словом following, узлы вставляются после каждого целевого узла.

В синтаксисе функциональных update-выражений вида TRANSFORM DELETE выражение locpath2($var1) определяет последовательность узлов, которые подлежат удалению из результата. Узлы удаляются вместе со всем их содержимым.

Ниже приводится формальное определение функциональных update-выражений вида TRANSFORM INSERT и TRANSFORM DELETE через выражения вида TRANSFORM REPLACE.

1) INSERT INTO

for $var1 in locpath1 transform insert into $var2 in locpath2($var1) value expr($var1,$var2)

определяется, как

for $var1 in locpath1 transform replace $var2 in locpath2($var1) with element {node-name($var2)} {($var2/@*,expr($var1,$var2),$var2/*)}

2) INSERT PRECEDING

for $var1 in locpath1 transform insert preceding $var2 in locpath2($var1) value expr($var1,$var2)

определяется, как

for $var1 in locpath1 transform replace $var2 in locpath2($var1) with (expr($var1,$var2),$var2)

3) INSERT FOLLOWING

for $var1 in locpath1 transform insert following $var2 in locpath2($var1) value expr($var1,$var2)

определяется, как

for $var1 in locpath1 transform replace $var2 in locpath2($var1) with ($var2, expr($var1,$var2))

4) DELETE

for $var1 in locpath1 transform delete locpath2($var1)

определяется, как

for $var1 in locpath1 transform replace $var2 in locpath2($var1) with ()

Далее мы рассмотрим некоторые подходы к реализации функциональных update-выражений. Будут выделены возможные ограничения семантики таких выражений, которые позволяют упростить реализацию и сделать ее более эффективной.




Выбор семантики функциональных update- выражений зависит от того, какие запросы к XML-данным являются более востребованными. Функциональные update-выражения с прямой семантикой соответствуют логике трансформации данных, когда необходимо трансформировать элементы без учета возможной их вложенности, то есть только XML-элементы, самые близкие к вершине XML-дерева, которые соответствуют критерию выборки. В отличие от этого, функциональные update-выражения с рекурсивной семантикой соответствуют логике обработки данных, когда необходимо выполнить рекурсивную трансформацию данных, то есть, при измении некоторым образом XML-элемента, удовлетворяющего критерию выборки, требуется выполнить трансформацию и его содержимого, если оно также удовлетворяет критерию выборки.

Нам представляется целесообразным расширять язык XQuery функциональными update-выражениями с рекурсивной семантикой, так как запросы, соответствующие такой семантике, более характерны для обработки иерархической структуры XML-данных.

Для более точного определения рекурсивной семантики функциональных update-выражений, мы приведем его 'эталонную' интерпретацию, в которой не учитываются вопросы эффективного вычисления, а лишь определяется результат вычисления функционального update-выражения.

Пусть даны дерево XML-документа T и функциональное update-выражение вида

for $var1 in locpath1 transform replace $var2 in locpath2($var1) with expr($var2)

1-ый шаг интерпретации:

Построить T' - полную копию исходного дерева документа T. Построение означает, что уникальные идентификаторы узлов дерева T' будут отличаться от уникальных идентификаторов соответствующих узлов дерева T. Все остальные элементы модели данных языка XQuery для деревьев T и T' будут совпадать. Поскольку построена полная копия, то результаты вычисления XPath-выражений locpath1 и locpath2 на деревьях T и T' будут совпадать.

2-ой шаг интерпретации:

Вычислить XPath-выражение locpath1 над XML-деревом T', получив последовательность узлов L1'. Для каждого узла из последовательности L1' получить последовательность узлов L2', являющуюся результатом вычисления выражения locpath2 над деревом T'.

3-ий шаг интерпретации:

Представить последовательность L2' в обратном порядке документа, получая последовательность L2''.

4-ый шаг интерпретации:

Каждый узел из последовательности L2'', начиная с первого, заменить последовательностью узлов, являющихся результатом вычисления выражения expr на дереве T'.

5-ый шаг интерпретации:

Вернуть последовательность XML-узлов L1'. Если в результате выполнения 4-го шага интерпретации, какой-либо из узлов последовательности L1' был заменен последовательностью узлов, то в результат добавляется вся эта последовательность узлов.


Содержание раздела