Jak stworzyć wartość logiczną?

86

Jestem zupełnie nowy w XSLT i nie mogę ustalić, gdzie popełniam błąd z następującym kodem.

<xsl:variable name="var" select="boolean('false')"/>

<xsl:if test="$var'">variable is true</xsl:if>

Zawsze zwraca prawdę, jeśli ma być fałszywa. Czemu?

sydlawrence
źródło
3
To tylko sugestia, ale możesz uzyskać lepszą odpowiedź, jeśli napiszesz tytuł jako właściwe pytanie i unikniesz mówienia l33t.
Will Dean

Odpowiedzi:

168

Wartość zmiennej $ var zdefiniowana w:

   <xsl:variable name="var" select="boolean('false')"/>

jest

   true()

Dzieje się tak, ponieważ w XPath „ false” jest zwykłym łańcuchem, w przeciwieństwie do false()konstruktora booleanwartościfalse()

Dwie wartości logiczne w XPath to (zwróć uwagę, że są zbudowane!):

   true() i false()

Szczegóły konwersji dowolnej wartości na wartość logiczną są opisane w specyfikacji XPath :

„Funkcja boolowska konwertuje swój argument na wartość logiczną w następujący sposób:

  • liczba jest prawdziwa wtedy i tylko wtedy, gdy nie jest ani dodatnim, ani ujemnym zerem, ani NaN

  • zestaw węzłów jest prawdziwy wtedy i tylko wtedy, gdy nie jest pusty

  • łańcuch jest prawdziwy wtedy i tylko wtedy, gdy jego długość jest różna od zera

  • obiekt typu innego niż cztery podstawowe typy jest konwertowany na wartość logiczną w sposób zależny od tego typu "

W twoim przypadku ciąg „fałsz” nie jest liczbą 0 i ma dodatnią długość, więc stosowana jest reguła z trzeciego punktu powyżej, dając wynik true().

Dlatego też, aby zdefiniować zmienną w XSLT 1.0, której wartość to false() , należy zapisać definicję w następujący sposób:

   <xsl:variable name="vMyVar" select="false()"/>

lub, jeśli nie pamiętasz tego dokładnie, zawsze możesz napisać:

   <xsl:variable name="vMyVar" select="1 = 0"/>

(określ dowolne wyrażenie, którego wynikiem jest false()), a procesor XSLT wykona pracę za Ciebie.

W XSLT 2.0 zawsze lepiej jest jawnie określić typ zmiennej:

   <xsl:variable name="vMyVar" as="xs:boolean" select="false()"/>

Dimitre Novatchev
źródło
@DimitreNovatchev Cześć Dimitre. Jest to rozwiązanie, jeśli wartość logiczna jest zakodowana na stałe w pliku transformacji XSL. Czy istnieje zgrabne rozwiązanie dla falsei trueciągów znaków pochodzących z transformowanego pliku, które nie obejmuje porównywania ciągów?
Jagger
1
@Jagger, to jest na inne pytanie. To pytanie dotyczy „ Jak stworzyć wartość logiczną ” i ma dokładną odpowiedź. Pytasz: „ Jak interpretować (lub parsować) poszczególne ciągi na wartości logiczne ” - to jest zupełnie inne pytanie. Czy mogę zapytać, co jest nie tak z porównaniem ciągów?
Dimitre Novatchev
17

Funkcja boolean (), której używasz, rzeczywiście wykonuje swoją pracę. Aby użyć jawnych wartości prawda i fałsz, należy użyć następujących funkcji:

<xsl:variable name="var_false" select="false()"/>
<xsl:variable name="var_true" select="true()"/>

Po prostu do Twojej wiadomości, zgodnie z dokumentacją MSDN , boolean () zwraca następujące dane:

  • Jeśli argument jest liczbą ujemną lub dodatnią, jest konwertowany na wartość logiczną true.
  • Jeśli argument ma wartość zero lub wartość NaN, jest konwertowany na fałsz.
  • Jeśli argument jest niepustym zestawem węzłów, jest konwertowany na wartość true. Pusty zestaw węzłów jest konwertowany na fałsz.
  • Jeśli argument jest niepustym łańcuchem, jest konwertowany na wartość true . Pusty ciąg jest konwertowany na fałsz.
  • Jeśli argument jest obiektem typu innego niż cztery typy podstawowe, jest konwertowany na wartość logiczną w sposób zależny od tego typu.
Yuval Adam
źródło
Powinieneś przeformatować przedostatnią pozycję listy, aby bardziej się wyróżniała, ponieważ jest ona kluczowa. „boolean ('')” również dałoby fałsz.
Tomalak
2
@Tomalak, zobacz moją odpowiedź. Jest trochę bardziej szczegółowy i cytuje prawdziwe źródło: specyfikację W3C XPath, a nie „MSDN”.
Dimitre Novatchev,
1
@Dimitre: Nie sądzę, aby MSDN zbytnio odbiegało od specyfikacji W3C pod tym względem. :) Ale wskazanie tam jest oczywiście bardziej poprawne.
Tomalak
5

Być może trochę późno na tym etapie, ale radzenie sobie z wartościami logicznymi nie jest po prostu warte wysiłku. Oto jak poradziłem sobie z wartością logiczną (obowiązkową) wracającą z bazy danych:

<xsl:variable name="vTrue" select="true()"/>                     
    <xsl:choose>
      <xsl:when test="string(Mandatory) = string($vTrue)">
        <xsl:text>Mandatory</xsl:text>
      </xsl:when>
      <xsl:otherwise>           
      </xsl:otherwise>
    </xsl:choose>

Mam nadzieję, że to komuś pomoże

outcoolnames
źródło