Работа с последовательностями¶
Задача¶
Вы хотите манипулировать наборами произвольных узлов и атомарных значений, взятых из одного или нескольких 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.