Результат остатка от деления имеет тот же знак, что и делимое. Этот факт можно использовать для того, чтобы выполнять деление без остатка, например число A
можно нацело разделить на число B
выражением (A - (A mod B)) div B
.
Пример:
(3.2 - (3.2 mod 2)) div 2
→ 1
Во избежание ошибок следует аккуратно использовать знак вычитания в арифметических операциях. Дело в том, что синтаксис XML разрешает использовать символ " -
" в именах элементов, которые в свою очередь также могут быть использованы в выражениях в составе путей выборки. Например, A - B
означает разность A
и B
, в то время как A-B
будет воспринято, как имя ' A-B
'. Поэтому рекомендуется выделять знак минуса пробелами.
Приведем продукции выражений с арифметическими операциями.
Унарному отрицанию соответствует продукция UnaryExpr
. Как можно видеть, в текущей версии языка это — единственная унарная операция (то есть операция одного элемента).
[XP27] UnaryExpr ::= UnionExpr | '-' UnaryExpr
Попробуем упростить это правило, раскрыв рекурсию
UnaryExpr ::= '-' * UnionExpr
Таким образом, унарное отрицание можно повторять несколько раз:
------5
→ 5
Умножению, делению и вычислению остатка деления соответствует одна продукция MultiplicativeExpr
:
[XP26] MultiplicativeExpr ::= UnaryExpr
| MultiplicativeExpr MultiplyOperator UnaryExpr
| MultiplicativeExpr 'div' UnaryExpr
| MultiplicativeExpr 'mod' UnaryExpr
Оператор умножения вынесен в отдельное правило:
[XP34] MultiplyOperator ::= '*'
Сложению и вычитанию соответствует правило AdditiveExpr
:
[XP25] AdditiveExpr ::= MultiplicativeExpr
| AdditiveExpr '+' MultiplicativeExpr
| AdditiveExpr '-' MultiplicativeExpr
XPath позволяет сравнивать числа при помощи операторов, перечисленных в табл. 6.4.
Таблица 6.4. Операторы сравнения
Оператор |
Значение |
= |
Равно |
!= |
Не равно |
< |
Меньше |
> |
Больше |
<= |
Меньше или равно (не больше) |
>= |
Больше или равно (не меньше) |
XPath-выражения чаще всего используются в значениях атрибутов, символ " <
" в которых в соответствии с синтаксисом XML использовать нельзя. Поэтому операторы сравнения "меньше" (" <
") и "не больше" (" <=
") нужно записывать с использованием сущностей. Оператор "меньше" может быть записан как " <
;", а оператор "не больше" как " <=
".
Пример
Результатом обработки элемента
будет строка " true
".
Сравнение всегда требует наличия двух операндов числового типа. Если операнды не являются числами, они будут соответствующим образом преобразованы.
В XPath вполне корректным будет выражение вида A > B > C
. Однако результат его будет довольно неожиданным. В XPath действует правило левой ассоциативности операторов сравнения, поэтому A > B > C
будет равносильно (А > B) > C
. То есть A
будет сравнено с B
, затем результат, истина или ложь, будет преобразован в числовой тип (получится 1
или 0
) и затем сравнен со значением C
.
Пример:
3 > 2 > 1
→ (3 > 2) > 1
→ 1 > 1
→ false
3 > 2 > 0
→ (3 > 2) > 0
→ 1 > 0
→ true
Неравенствам в XPath соответствует продукция RelationalExpr
:
[XP24] RelationalExpr ::= AdditiveExpr
| RelationalExpr '<' AdditiveExpr
| RelationalExpr '>' AdditiveExpr
| RelationalExpr '<=' AdditiveExpr
| RelationalExpr '>=' AdditiveExpr
Операции "равно" и "не равно" записываются при помощи продукции
EqualityExpr:
[XP23] EqualityExpr ::= RelationalExpr
| EqualityExpr '=' RelationalExpr
| EqualityExpr '!=' RelationalExpr
Операции с множествами узлов
Три основные операции с множествами узлов, которые поддерживает язык XPath, — это фильтрация множества, выборка с использованием путей и объединение.
Множества узлов, которые получаются в результате вычисления выражений, можно фильтровать — то есть выбирать из них узлы, удовлетворяющие заданным свойствам подобно тому, как это делалось предикатами в шагах выборки.
В выражениях множества узлов могут также фильтроваться одним или несколькими предикатами. Узел остается в фильтруемом множестве, только если он удовлетворяет всем предикатам поочередно.
Пример
Предположим, что нам нужно оставить в фильтруемом множестве узлов, которое присвоено переменной nodes
, только те узлы, которые имеют имя а
и атрибут href
. Искомое выражение может быть записано следующим образом:
Читать дальше