Xsl: когда тест с несколькими условиями рассматривается как "или" вместо "и",
Я пытаюсь создать инструкцию xsl: select с несколькими условиями для тестирования. Пока у меня есть это:
<xsl:choose>
<xsl:when test="$AccountNumber != '12345' and $Balance != '0'">
<do stuff here>
...
Проблема заключается в том, что "и" рассматривается как "или". Если номер учетной записи 12345 или баланс учетной записи равен 0, условие считается истинным и код запускается. Мне нужно, чтобы тест состоял в том, что оба условия должны быть истинными. У меня здесь синтаксис?
Спасибо заранее,
~ Тим
Ответы
Ответ 1
Проблема заключается в том, что "и" рассматривается как "или".
Нет, проблема в том, что вы используете оператор XPath !=
, и вы не знаете его "странной" семантики.
Решение
Просто замените выражения x != y
выражением not(x = y)
.
В вашем конкретном случае:
Заменить
<xsl:when test="$AccountNumber != '12345' and $Balance != '0'">
с
<xsl:when test="not($AccountNumber = '12345') and not($Balance = '0')">
Объяснение
По определению, если один из операндов оператора !=
является узлом, то результат вычисления этого оператора является истинным, если в node -set есть node, значение которого не равно к другому операнду.
Так
$someNodeSet != $someValue
обычно не дает такого же результата, как:
not($someNodeSet = $someValue)
Последний (по определению) выполняется точно, когда в $someNodeSet
нет node, строковое значение которого равно $someValue
.
Урок для изучения:
Никогда не используйте оператор !=
, если вы не уверены, что знаете, что делаете.
Ответ 2
Если $AccountNumber
или $Balance
является node -set, то такое поведение может быть легко осуществлено. Это не потому, что and
рассматривается как or
.
Например, если $AccountNumber
ссылается на узлы со значениями 12345
и 66
и $Balance
, ссылающимися на узлы со значениями 55
и 0
, то
$AccountNumber != '12345'
будет истинным (поскольку 66
не равно 12345
), а $Balance != '0'
будет истинным (поскольку 55
не равно 0
).
Я бы попробовал это вместо этого:
<xsl:when test="not($AccountNumber = '12345' or $Balance = '0')">
$AccountNumber = '12345' or $Balance = '0'
будет истинным в любое время, когда есть $AccountNumber
со значением 12345
или есть $Balance
со значением 0
, и если вы примените к нему not()
, вы получите ложный результат.
Ответ 3
Я всегда использовал этот синтаксис, который дает более предсказуемые результаты, чем использование! =.
<xsl:when test="not($AccountNumber = '12345') and not($Balance = '0')" />