Sei que essa pergunta é antiga, mas entre todas as respostas, sinto falta de uma que seja uma abordagem comum para esse caso de uso no desenvolvimento de XSLT.
Estou imaginando que o código ausente do OP se parece com isso:
<xsl:template match="category">
<xsl:choose>
<xsl:when test="categoryName !=null">
<xsl:value-of select="categoryName " />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="other" />
</xsl:otherwise>
</xsl:choose>
</category>
E que a entrada se parece com isso:
<categories>
<category>
<categoryName>Books</categoryName>
</category>
<category>
<categoryName>Magazines</categoryName>
<categoryName>Periodicals</categoryName>
<categoryName>Journals</categoryName>
</category>
<category>
<categoryName><!-- please fill in category --></categoryName>
</category>
<category>
<categoryName />
</category>
<category />
</categories>
Ou seja, suponho que pode haver zero, vazio, único ou vários categoryName
elementos. 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 idioma típico de programação no XSLT está usando modelos (daí o T no XSLT), que é uma programação declarativa, não imperativa (você não diz ao processador o que fazer, apenas diz o que deseja obter, se determinadas condições forem atendidas). Para este caso de uso, isso pode ser algo como o seguinte:
<!-- positive test, any category with a valid categoryName -->
<xsl:template match="category[categoryName[text()]]">
<xsl:apply-templates />
</xsl:template>
<!-- any other category (without categoryName, "null", with comments etc) -->
<xsl:template match="category">
<xsl:text>Category: Other</xsl:text>
</xsl:template>
<!-- matching the categoryName itself for easy handling of multiple names -->
<xsl:template match="categoryName">
<xsl:text>Category: </xsl:text>
<xsl:value-of select="." />
</xsl:template>
Isso funciona (com qualquer versão XSLT), porque o primeiro acima tem uma precedência mais alta (tem um predicado). O modelo correspondente "fall-through", o segundo, captura qualquer coisa que não seja válida. O terceiro, então, cuida da saída docategoryName
valor de maneira adequada.
Observe que, nesse cenário, não há necessidade de corresponder categories
oucategory
camente , porque o processador processará automaticamente todos os filhos, a menos que seja indicado o contrário (neste exemplo, o segundo e o terceiro modelo não processam mais os filhos, porque não háxsl:apply-templates
em eles).
Essa abordagem é mais facilmente extensível 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
XML. Existe xsi: nil , mas isso raramente é usado, especialmente raramente em cenários sem tipo, sem um esquema de algum tipo.