Перемещение поддерева
При наличии введенного понятия базового узла перемещение поддерева может быть реализовано совокупностью двух операций модификации. На основе рассмотренной семантики вычисления нескольких операций модификации узел– корень поддерева, подлежащего перемещению, – может выступать в роли обрабатываемого узла для первой из двух операций модификации и в роли базового узла — для второй операции. Эффект перемещения поддерева достигается тогда, когда первая операция модификации удаляет свой обрабатываемый узел из документа, а вторая операция вставляет в документ свой базовый узел (являющийся обрабатываемым узлом для предыдущей операции модификации). Поскольку обе операции являются компонентами единого запроса на модификацию, влияние этих операций на обрабатываемый документ атомарно и с точки зрения реализации осуществляется за один проход по дереву документа.
Введенное правило вычисления базового узла естественным образом подходит для операции перемещения поддерева, потому что в практических задачах модификации новое местоположение перемещаемого поддерева часто задается относительно его исходного местоположения, и как раз при этом условии обрабатываемый узел первой из двух операций модификации, осуществляющих перемещение, становится базовым узлом для второй операции модификации.
Поскольку перемещение поддерева включает в себя удаление поддерева в его старом местоположении и вставку поддерева в новое местоположение, при формализации соответствующих действий в виде обработчиков могут быть почти без изменений использованы обработчики, рассмотренные в разделе . В зависимости от различных способов вставки перемещаемого поддерева на его новое местоположение разумно различать такие варианты, как “перемещение перед”, “перемещение после” и “перемещение внутрь”, соответствующие аналогичным вариантам операции вставки узла.
Пример 5 Предположим, что электронная версия некоторой книги состоит из элементов с именем глава (chapter), и каждая глава содержит элементы с именем параграф
(para). Переместим последний параграф главы, имеющей заголовок “Введение” (“Introduction”), в следующую по порядку главу в качестве ее первого параграфа.
Запрос на желаемую модификацию реализуется следующей совокупностью из двух операций модификации, связанных друг с другом посредством базового узла:
(sxml:modify `("/book/chapter[title='Introduction']/ para[last()]" ,(lambda (node base-node) '())) `("following::chapter[1]/para[1]" ,(lambda (node base-node) (list base-node node))))
Первая операция модификации выбирает параграф, подлежащий перемещению, и удаляет его по месту его исходного положения. Обрабатываемый параграф, удаленный из документа первой операцией модификации, тем не менее, является базовым узлом для второй операции модификации, поскольку во второй операции модификации в качестве выражения XPath используется относительный путь доступа. Вторая операция модификации осуществляет вставку перемещаемого параграфа – базового узла base-node – перед первым по счету параграфом главы, следующей за главой с заголовком “Введение”. Совокупный эффект обоих операций модификации рассматриваемого примера обеспечивает желаемое перемещение узла.
Необходимо отметить, что обе операции модификации рассмотренного примера являются составляющими одного запроса на модификацию, и поэтому с точки зрения реализации, детали которой обсуждаются в разделе , выполняются за один проход по дереву обрабатываемого документа.