Перейти к содержанию

Работа с последовательностями

Задача

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

Решение

XPath 1.0

В версии XPath 1.0 нет понятия последовательности, а потому приведенные ниже рецепты к ней как правило неприменимы. В XPath 1.0 есть наборы узлов. Вот идиоматический способ сконструировать пустой набор узлов в XPath 1.0:

Пустой набор узлов: /..

XPath 2.0

Конструктор пустой последовательности: ()

Последовательность, состоящая из единственного атомарного элемента со значением 1: 1

Сконструировать последовательность с помощью оператора "запятая". Здесь мы строим последовательность, в которую входят все дочерние элементы контекстного узла с именем X, затем элементы с именем Y и затем элементы с именем Z: X, Y, Z

Применение оператора to для конструирования диапазона: 1 to 10

Сочетание оператора "запятая" и нескольких диапазонов: 1 to 10, 100 to 110, 17, 19, 23

Можно включать также переменные и функции: 1 to $x, 1 to count(para)

Последовательности не бывают вложенными, поэтому следующие два примера дают одинаковый результат: ((1,2,3), (4,5,(6,7),8,9,10)), 1,2,3,4,5,6,7,8,9,10

Оператор to не может создавать убывающие диапазоны (Эта последовательность пуста!): 10 to 1

Но нужного результата можно достичь таким способом: for $n in 1 to 10 return 11 - $n

Удалить из последовательности дубликаты: distinct-values($seq)

Вернуть длину последовательности: count($seq)

Проверить, пуста ли последовательность: empty($seq) (это лучше, чем count($seq) eq 0)

Найти, в каких позициях последовательности находится данный элемент. Функция index-of возвращает последовательность целых чисел, соответствующих позициям тех элементов последовательности, заданной первым аргументом, которые имеют значение, равное второму аргументу: index-of($seq, $item)

Не более трех элементов $seq, начиная со второго: subsequence($seq, 2, 3)

Элементы $seq, начиная с третьего и до конца: subsequence($seq, 3)

Вставить последовательность $seq2 перед третьим элементом последовательности $seq1: insert-before($seq1, 3, $seq2)

Построить новую последовательность, которая содержит все элементы $seq, кроме третьего: remove($seq, 3)

Для удаления нескольких элементов можно воспользоваться выражениями такого вида: $seq1[not(position() = (1,3,5))], $seq1[position() gt 3 and position() lt 7]

Обсуждение

В XPath 2.0 каждый элемент данных (значение) является последовательностью. Таким образом, атомарное значение 1 – последовательность, как и результат вычисления выражения (1 to 10). Подругому эту мысль можно выразить, сказав, что вычисление любого выражения в XPath 2.0 дает последовательность. Последовательность может содержать нуль и более элементов, в качестве которых могут выступать узлы и атомарные значения в любом сочетании. При сравнении последовательностей порядок существенен. Нумерация элементов начинается с 1 (а не с 0, как в языках C и Java).

В XPath 1.0 нет последовательностей, но есть наборы узлов. Набор узлов не так удобен, но во многих случаях различие несущественно. Например, любое выражение XPath 1.0, в котором используются функции count() и empty(), ведет себя так же, как в версии 2.0. Преимущество XPath 2.0 заключается в том, что последовательности – это полноценные конструкции, для создания и манипулирования которыми имеются многочисленные функции, включенные в версию 2.0.