Книга: Технология XSLT
Операции сравнения
Операции сравнения
В XSLT имеются следующие шесть операторов сравнения:
? "=
" — равно;
? "!=
" — не равно;
? "<
" меньше;
? ">
" больше;
? "<=
" меньше или равно (не больше);
? ">=
" больше или равно (не меньше).
Результат этих сравнений всегда имеет булевый тип, то есть сравнение может быть либо истинным, либо ложным. Несмотря на внешнюю очевидность функций этих операторов, наличие такого типа данных, как множество узлов, делает четкое определение сравнений довольно сложным. Мы приведем его так, как оно приведено в спецификации, снабдив подробными комментариями и примерами.
Операции сравнения определяются в спецификации в три этапа:
? сначала сравнение, в котором участвуют множества узлов, определяется в терминах сравнения более простых типов данных;
? затем для простых типов данных определяются равенство ("=
") и неравенство ("!=
");
? наконец, для простых типов данных определяются сравнения "<
", "<=
", ">
", ">=
".
Сравнение, хотя бы один из операндов которого является множеством узлов, определяется следующим образом:
? если один из операндов является множеством узлов, а второй имеет булевый тип, сравнение будет истинным тогда и только тогда, когда истинным будет результат сравнения множества узлов, преобразованного к булевому типу и самого булевого операнда;
? если один из операндов является множеством узлов, а второй имеет численный тип, сравнение будет истинным тогда и только тогда, когда во множестве узлов найдется такой узел, что сравнение текстового значения этого узла, преобразованного к числу, и самого численного операнда будет истинным;
? если один из операндов является множеством узлов, а второй имеет строковый тип, сравнение будет истинным тогда и только тогда, когда во множестве узлов найдется такой узел, что сравнение его текстового значения и самого строкового операнда будет истинным;
? если оба операнда являются множествами узлов, их сравнение будет истинным тогда и только тогда, когда найдется узел в первом множестве и узел во втором множестве, такие, что их сравнение будет истинным.
Примеры выражений, которые мы будем приводить, будут использовать следующий входящий документ (листинг 3.25).
Листинг 3.25. Входящий документ
<values>
<string>0.5</string>
<string>50%</string>
<string>1/2</string>
<number>0.5</number>
<number>1.0</number>
<number>1.5</number>
</values>
Примеры сравнений множества узлов с булевым значением:
/values/string = true()
? true
В этом равенстве множество узлов сравнивается с булевым значением "истины". Множество узлов, выбираемое путем /values/string
, приводится к булевому типу. Результатом приведения будет "истина", поскольку множество элементов string, принадлежащих элементу values
, непусто. Таким образом, сравнение является проверкой на равенство двух "истин" — и результат, естественно, тоже будет "истиной".
/values/string != boolean(/values/boolean)
? false
В этом случае мы проверяем множество узлов /values/string
на неравенство булевому значению множества /values/boolean
. Второй операнд является "истиной" (поскольку множество элементов boolean
, принадлежащих элементу values
, не пусто), а значит, все сравнение обратится в "ложь".
/values/string = boolean(/values/booleans)
? false
В данном случае множество /values/string
сравнивается с булевым значением множества /values/booleans
, которое будет "ложью", поскольку это множество будет пустым. Таким образом, результат сравнения также будет "ложью".
/values/strings = boolean(/values/booleans)
? true
Множества /values/strings
и /values/booleans
будут пустыми, поэтому, сравнивая первое с булевым значением второго, мы получим "истину", так как "ложь" равна "лжи".
Примеры сравнения множества узлов с числом:
/values/number < 1
? true
Множество узлов /values/number
может считаться меньше, чем число 1
, поскольку первый элемент этого множества имеет строковое значение "0.5
", при приведении которого к числу мы получаем 0.5
, что меньше 1
.
/values/number > 1
? true
То же самое множество узлов может считаться также и большим 1
, поскольку последний элемент этого множества имеет строковое значение "1.5
", при приведении которого к числу мы получаем 1.5
, что больше 1
.
/values/number = 1
? true
Второй элемент множества /values/number
равен 1
, то есть и это сравнение будет истинным.
Примеры сравнения множества узлов со строковым значением:
/values/number = '1'
? false
Множество /values/number
не будет равно строке "1
", поскольку ни один из узлов этого множества не имеет строкового значения "1
".
/values/number = '1.0'
? true
Множество /values/number
будет считаться равным строке "1.0
", поскольку второй узел этого множества имеет текстовое значение "1.0
".
/values/number != '1.0'
? true
Множество /values/number
может также считаться не равным строке "1.0
", поскольку первый узел этого множества имеет текстовое значение "0.5
", не равное "1.0
".
Примеры сравнения двух множеств узлов:
/values/number = /values/string
? true
Для двух этих множеств будет выполняться равенство, поскольку оба они имеют по узлу с равными строковыми значениями — первый узел /values/number
и первый узел /values/string
равны "0.5
".
values/number != /values/string
? true
Для этих же множеств будет выполняться неравенство, поскольку в них найдется неравная пара узлов (например, узел с текстовым значением "1.0
" в /values/number
и узел с текстовым значением "50%
" в /values/string
).
Определим теперь равенство и неравенство значений простых типов. При проверке на равенство или неравенство оба операнда приводятся к общему типу и сравниваются. Приведение к общему типу производится следующим образом:
? если хотя бы один из операндов имеет булевый тип, второй также приводится к булевому типу;
? иначе, если хотя бы один из операндов — число, второй также приводится к численному типу;
? иначе, если хотя бы один из операндов — строка, второй также приводится к строковому типу.
После того, как оба операнда приведены к некоторому общему типу, они проверяются на равенство или неравенства как два значения этого общего типа:
? два булевых значения равны тогда и только тогда, когда они оба являются "истиной" или оба являются "ложью";
? равенство численных значений понимается в обычном смысле (строгое определение равенства чисел дано в стандарте IEEE 754, но вряд ли оно представляет для нас большой интерес);
? две строки равны тогда и только тогда, когда они представлены одинаковыми последовательностями Unicode-символов.
Два значения простых типов (то есть — булевого, численного или строкового типа) неравны тогда и только тогда, когда для них не выполняется равенство.
Примеры сравнения значений простых типов:
? true() = 1
? true
При приведении числа 1
к булевому типу получается "истина", что и подтверждается этим равенством.
? true() = 100
? true
Результатом приведения числа 100
к булевому типу также является "истина".
? false() = 'false'
? false
При приведении непустой строки "false" к булевому типу, получается "истина". Отсюда — неверность равенства.
? .5 =0.5
? true
и
.50.5
представляют одно и то же число, хоть и они записаны в разной форме.
? .5 = '0.5'
? true
Это равенство также будет верным, поскольку результатом преобразования строки "0.5
" в число будет также 0.5
.
? 1 != 'two'
? true
Результатом преобразования строки "two
" в численный тип будет значение NaN
, которое не равно 1
.
При сравнении с использованием операторов "<
", "<=
", ">
" и ">=
", оба операнда всегда приводятся к численному типу и сравниваются как числа.
Примеры сравнений с использованием операторов "<
", "<=
", ">
" и ">=
":
false () > true()
? false
В численном виде true()
соответствует 1
, a false()
— 0
, то есть это сравнение равносильно сравнению 0 > 1
, результатом которого является "ложь".
'0' <= false()
? true
Это сравнение равносильно сравнению 0 <= 0
, результатом его будет "истина".
'1' >= '0'
? true
Это сравнение равносильно сравнению 1 >= 0
, результатом его будет "истина".
Следует обратить внимание, на то, что символы "<
" и ">
" заменены сущностями <
и >
соответственно. В случае символа "<
" такая замена необходима, чтобы не нарушать выражениями синтаксис XML-документа. Заменять символ ">
" обязательной нужды нет, это делается исключительно из соображений единообразности.
- Операции с множествами узлов
- 2. Унарные операции на языке структурированных запросов
- Операции отношения
- Операции с полями BLOB
- Конструкции выбора решений и операции сравнения
- 7.3. Операции сравнения
- Пример 7-5. Операции сравнения
- 33.3. Операции сравнения: Альтернативные решения
- 2.2.1 Операции сравнения
- 4. Лекция: Типы данных