Verifique se uma string é nula ou vazia no XSLT

Como posso verificar se um valor é nulo ou vazio com XSL ?

Por exemplo, se categoryName estiver vazio? Eu estou usando um quando escolher construir.

Por exemplo:

         

 test="categoryName != ''" 

Edit : Isso cobre a interpretação mais provável, na minha opinião, de “[não] nulo ou vazio”, como inferido da pergunta, incluindo seu pseudo-código e minha própria experiência inicial com XSLT. Ou seja, “Qual é o equivalente do seguinte Java?”:

 !(categoryName == null || categoryName.equals("")) 

Para mais detalhes, por exemplo, identificando nitidamente null versus empty, veja a resposta de johnvey abaixo e / ou o “violino” XSLT que adaptei a partir dessa resposta, que inclui a opção no comentário de Michael Kay, bem como a sexta possível interpretação.

Ausente de qualquer outra informação, assumirei o seguinte XML:

   item 1 blue   item 2    item 3  ...  

Um caso de uso de amostra seria semelhante a:

               

Do elemento vazio :

Para testar se o valor de um determinado nó está vazio

Depende do que você quer dizer com vazio.

  • Não contém nós filhos: not(node())
  • Não contém conteúdo de texto: not(string(.))
  • Não contém texto diferente de espaço em branco: not(normalize-space(.))
  • Não contém nada, exceto comentários: not(node()[not(self::comment())])

Sobre o quê?

 test="not(normalize-space(categoryName)='')" 

Os dois primeiros lidam com valor nulo e os segundos dois lidam com string vazia.

  USERNAME is not null   USERNAME is null   USERNAME is empty string   USERNAME is not empty string  

Em alguns casos, talvez você queira saber quando o valor é especificamente nulo, o que é particularmente necessário ao usar o XML que foi serializado a partir de objects .NET. Enquanto a resposta aceita funciona para isso, ele também retorna o mesmo resultado quando a string está em branco ou vazia, ou seja, ”, então você não pode diferenciar.

   item 1    

Então você pode simplesmente testar o atributo.

  Hello World.  

Às vezes é necessário saber o estado exato e você não pode simplesmente verificar se CategoryName é instanciado, porque ao contrário do JavaScript

  Hello World.  

Retornará true para um elemento nulo.

Eu sei que esta questão é antiga, mas entre todas as respostas, eu sinto falta de uma que é uma abordagem comum para este caso de uso no desenvolvimento de XSLT.

Eu estou imaginando que o código em falta do OP é algo como isto:

           

E que a input se parece com algo assim:

   Books   Magazines Periodicals Journals          

Ou seja, eu suponho que pode haver zero, vazio, único ou vários elementos categoryName . Para lidar com todos esses casos usando xsl:choose – construções de estilo, ou em outras palavras, imperativamente, está ficando rapidamente confuso (ainda mais se os elementos puderem estar em níveis diferentes!). Um típico idioma de programação no XSLT é usar templates (daí o T no XSLT), que é uma programação declarativa, não imperativa (você não diz ao processador o que fazer, você apenas diz o que você quer se determinadas condições forem atendidas). Para este caso de uso, pode ser algo como o seguinte:

       Category: Other    Category:    

Isso funciona (com qualquer versão XSLT), porque o primeiro acima tem uma precedência mais alta (ele tem um predicado). O modelo de correspondência “fall-through”, o segundo, captura tudo o que não é válido. O terceiro, então, cuida da saída do valor categoryName maneira apropriada.

Observe que, nesse cenário, não há necessidade de corresponder especificamente categories ou category , porque o processador processará automaticamente todos os filhos, a menos que seja dito de outra forma (neste exemplo, o segundo e o terceiro modelo não processam mais os filhos, porque há no xsl:apply-templates neles).

Essa abordagem é mais facilmente extensível do que a abordagem imperativa, porque lida automaticamente com várias categorias e pode ser expandida para outros elementos ou exceções apenas adicionando outro modelo correspondente. Programação sem if-branches .

Nota: não existe null em XML. Há xsi: nil , mas isso raramente é usado, especialmente raramente em cenários não tipificados sem um esquema de algum tipo.

Se houver a possibilidade de que o elemento não exista no XML, testaria que o elemento está presente e que o tamanho da string é maior que zero:

         

Se um nó não tiver valor disponível no xml de input, como abaixo do xpath,

    

A function string () é convertida em valor vazio. Então isso funciona bem:

 string(/Node/ErrorCode) ='' 

Algo assim funciona para mim:

   -      

Ou o contrário:

      -   

Nota: Se você não verificar valores nulos ou manipular valores nulos, o IE7 retornará -2147483648 em vez de NaN.

Como posso verificar se um valor é nulo ou vazio com XSL?

Por exemplo, se categoryName estiver vazio?

Esta é provavelmente a expressão XPath mais simples (a resposta aceita fornece um teste para o oposto e seria mais longa, se negada):

 not(string(categoryName)) 

Explicação :

O argumento para a function not() acima é false() exatamente quando não há categoryName child (“null”) do item de contexto, ou o (single such) categoryName child tem valor de string – a string vazia.

Eu estou usando um quando escolher construir.

Por exemplo:

         

No uso do XSLT 2.0 :

  

Aqui está um exemplo completo :

        

Quando essa transformação é aplicada no seguinte documento XML:

 X 

o resultado desejado e correto é produzido :

 X 

Quando aplicado neste documento XML :

  

ou sobre isso:

  

ou neste

 Y 

o resultado correto é produzido :

 Other 

Da mesma forma, use esta transformação XSLT 1.0 :

        

Observe : nenhum condicional é usado. Aprenda mais sobre a importância de evitar construções condicionais neste bom curso Pluralsight:

Padrões de design tático no .NET: stream de controle

Pela minha experiência, a melhor maneira é:

       

Use categoryName simples / text () Esse teste funciona bem em e também .

         

Eu realmente achei melhor apenas testar o tamanho da string, pois muitas vezes o campo não é nulo, apenas vazio