Книга: Технология 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 &lt; 1 ? true

Множество узлов /values/number может считаться меньше, чем число 1, поскольку первый элемент этого множества имеет строковое значение "0.5", при приведении которого к числу мы получаем 0.5, что меньше 1.

/values/number &gt; 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
.5
и 0.5 представляют одно и то же число, хоть и они записаны в разной форме.

.5 = '0.5' ? true

Это равенство также будет верным, поскольку результатом преобразования строки "0.5" в число будет также 0.5.

1 != 'two' ? true

Результатом преобразования строки "two" в численный тип будет значение NaN, которое не равно 1.

При сравнении с использованием операторов "<", "<=", ">" и ">=", оба операнда всегда приводятся к численному типу и сравниваются как числа.

Примеры сравнений с использованием операторов "<", "<=", ">" и ">=":

false () &gt; true() ? false

В численном виде true() соответствует 1, a false()0, то есть это сравнение равносильно сравнению 0 > 1, результатом которого является "ложь".

'0' &lt;= false() ? true

Это сравнение равносильно сравнению 0 <= 0, результатом его будет "истина".

'1' &gt;= '0' ? true

Это сравнение равносильно сравнению 1 >= 0, результатом его будет "истина".

Следует обратить внимание, на то, что символы "<" и ">" заменены сущностями &lt; и &gt; соответственно. В случае символа "<" такая замена необходима, чтобы не нарушать выражениями синтаксис XML-документа. Заменять символ ">" обязательной нужды нет, это делается исключительно из соображений единообразности.

Оглавление книги


Генерация: 0.029. Запросов К БД/Cache: 0 / 0
поделиться
Вверх Вниз