Como criar um valor booleano?

86

Sou totalmente novo em XSLT e não consigo descobrir onde estou errado com o código a seguir.

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

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

Ele está sempre retornando verdadeiro quando se pretende que seja falso. Por quê?

sydlawrence
fonte
3
Apenas uma sugestão, mas você pode muito bem obter um calibre de resposta melhor se escrever seu título como uma pergunta adequada e evitar o discurso l33.
Will Dean

Respostas:

168

O valor da variável $ var conforme definido em:

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

é

   true()

Isso ocorre porque no XPath " false" é uma string comum, ao contrário de false(), que é o construtor do booleanvalorfalse()

Os dois valores booleanos em XPath são (observe que eles são construídos!):

   true() e false()

Os detalhes da conversão de qualquer valor em booleano são descritos nas especificações XPath .:

"A função booleana converte seu argumento em um booleano da seguinte maneira:

  • um número é verdadeiro se e somente se não for zero positivo ou negativo nem NaN

  • um conjunto de nós é verdadeiro se e somente se não estiver vazio

  • uma string é verdadeira se e somente se seu comprimento for diferente de zero

  • um objeto de um tipo diferente dos quatro tipos básicos é convertido em um booleano de uma forma que depende desse tipo "

No seu caso, a string "false" não é o número 0 e tem um comprimento positivo, então a regra do terceiro marcador acima é aplicada, rendendo true().

Portanto, para definir uma variável em XSLT 1.0, cujo valor é false() , é necessário escrever a definição da seguinte forma:

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

ou, se você não se lembra exatamente disso, você pode escrever:

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

(especifique qualquer expressão que avalie como false()) e o processador XSLT fará o trabalho para você.

Em XSLT 2.0, é sempre melhor especificar explicitamente o tipo da variável:

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

Dimitre Novatchev
fonte
@DimitreNovatchev Hi Dimitre. Esta é a solução se o valor booleano estiver codificado no arquivo de transformação XSL. Existe uma solução elegante para o falsee truecordas provenientes do arquivo estar em transformação que não envolve comparação corda?
Jagger
1
@Jagger, Essa é outra pergunta. Esta pergunta pergunta " Como criar um valor booleano " e tem uma resposta precisa. Você está perguntando: " Como interpretar (ou analisar) strings específicas em valores booleanos " - esta é uma questão completamente diferente. Posso perguntar o que há de errado com a comparação de strings?
Dimitre Novatchev
17

A função boolean () que você está usando está realmente fazendo seu trabalho. Para usar valores verdadeiros e falsos explícitos, você deve usar as seguintes funções:

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

Apenas para sua informação, de acordo com a documentação do MSDN , boolean () retorna o seguinte:

  • Se o argumento for um número negativo ou positivo, ele será convertido para o valor booleano true.
  • Se o argumento for zero ou um valor NaN, ele será convertido em falso.
  • Se o argumento for um conjunto de nós não vazio, ele será convertido em verdadeiro. Um conjunto de nós vazio é convertido em falso.
  • Se o argumento for uma string não vazia, ele será convertido em verdadeiro . Uma string vazia é convertida em falsa.
  • Se o argumento for um objeto de um tipo diferente dos quatro tipos básicos, ele será convertido em um booleano de uma forma que depende desse tipo.
Yuval Adam
fonte
Você deve reformatar o penúltimo item de sua lista para se destacar mais, pois é o mais importante. "boolean ('')" também produziria false.
Tomalak
2
@Tomalak, veja minha resposta. É um pouco mais detalhado e cita a verdadeira fonte: o W3C XPath Spec, em vez de "MSDN".
Dimitre Novatchev
1
@Dimitre: Não acho que o MSDN se desvie muito das especificações do W3C a esse respeito. :) Mas apontar para é obviamente mais correto.
Tomalak
5

Talvez um pouco tarde neste estágio, mas lidar com booleanos simplesmente não vale o esforço. Veja como eu lidei com um booleano (obrigatório) voltando do DB:

<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>

Espero que isso ajude alguém

outofcoolnames
fonte