2013-03-20 17 views
22

Próbuję utworzyć instrukcję xsl: choose z wieloma warunkami do przetestowania. Do tej pory mam to:xsl: gdy test z wieloma warunkami traktowany jako "lub" zamiast "i"

<xsl:choose> 
    <xsl:when test="$AccountNumber != '12345' and $Balance != '0'"> 
     <do stuff here> 
     ... 

Problem polega na tym, że "i" jest traktowane jako "lub". Jeśli numer konta to 12345 lub saldo konta wynosi 0, warunek jest traktowany jako prawdziwy, a kod zostaje wykonany. Potrzebuję testu, aby oba warunki były prawdziwe ... czy mam tutaj niewłaściwą składnię?

Dzięki z góry, ~ Tim

+0

Mam nadzieję, że [ta strona] (http://www.java2s.com/Code/XML/XSLT-stylesheet/ifstatementwithandoperator.htm) pomoże –

+0

Co dokładnie zawierają zmienne $ AccountNumber i $ Balance? Puste zestawy węzłów mogą na przykład prowadzić do zaskakujących wyników, ponieważ '$ empty-node-set! = '0'' będzie fałszem. – nwellnhof

+0

Jak zdefiniowano $ AccountNumber i $ Balance? Proszę, pokaż nam to. – JLRishe

Odpowiedz

6

Jeśli $AccountNumber lub $Balance jest zbiorem wierzchołków, to zachowanie może łatwo się zdarzyć. To nie dlatego, że and jest traktowany jako or.

Na przykład, jeśli $AccountNumber określone węzły wartości 12345 i 66 i $Balance określonych węzłów z wartościami 55 i 0, następnie $AccountNumber != '12345' byłoby prawdziwe (ponieważ 66 nie jest równa 12345) i $Balance != '0' byłoby właściwe (ponieważ 55 nie jest równy 0).

Sugerowałbym próbuje to zamiast:

<xsl:when test="not($AccountNumber = '12345' or $Balance = '0')"> 

$AccountNumber = '12345' or $Balance = '0' będzie prawdziwe każdym razem istnieje $AccountNumber o wartości 12345 lub jest $Balance o wartości 0, a jeśli stosuje not() temu , otrzymasz fałszywy wynik.

+2

Dobre wykorzystanie praw De Morgana. – Dan

0

Zawsze używałem tej składni, która daje bardziej przewidywalne wyniki niż użycie! =.

<xsl:when test="not($AccountNumber = '12345') and not($Balance = '0')" /> 
+2

Obie formy są równie "przewidywalne", jeśli docenisz dokładnie to, co zdefiniowano jako znaczące. Jeśli '$ AccountNumber' jest zbiorem węzłów zawierającym więcej niż jeden węzeł, to' $ AccountNumber! = '12345'' i 'not ($ AccountNumber =' 12345 ')' oznacza _zasadniczo_ różne rzeczy - ten pierwszy jest prawdziwy, jeśli istnieje _any_ węzeł w zestawie o wartości innej niż 12345, druga tylko wtedy, gdy _none_ węzłów w zestawie ma wartość 12345. –

32

Problemem jest to, że „a” jest traktowany jako „lub”.

Nie, problemem jest to, że używasz operatora XPath != i nie jesteś świadomy jego "dziwnej" semantyki.

Rozwiązanie:

Wystarczy wymienić żadnych x != y wyrażeń z wyrażeniem not(x = y).

W Twoim konkretnym przypadku:

Wymień:

<xsl:when test="$AccountNumber != '12345' and $Balance != '0'"> 

z:

<xsl:when test="not($AccountNumber = '12345') and not($Balance = '0')"> 

Wyjaśnienie:

Z definicji za każdym razem, gdy jeden z operandów operatora != jest zbiorem węzłów, wynik oceny tego operatora jest prawdziwy, jeśli w zestawie węzłów znajduje się węzeł, którego wartość nie jest równa innemu argumentowi operacji.

Więc:

$someNodeSet != $someValue 

ogół nie dają ten sam wynik:

not($someNodeSet = $someValue) 

Ten ostatni (z definicji) jest prawdziwe dokładnie, kiedy nie jest węzłem w $someNodeSet którego wartość ciągu jest równa $someValue.

lekcja:

Nigdy użyć operatora !=, chyba że jesteś absolutnie pewien, że wiesz co robisz.