Sé que esta pregunta es antigua, pero entre todas las respuestas, echo de menos una que es un enfoque común para este caso de uso en el desarrollo de XSLT.
Me imagino que el código faltante del OP se ve así:
<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>
Y que la entrada se ve así:
<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>
Es decir, supongo que puede haber cero, elementos vacíos, únicos o múltiples categoryName
. Tratar todos estos casos usando xsl:choose
construcciones de estilo, o en otras palabras, imperativamente, se está volviendo rápidamente desordenado (¡aún más si los elementos pueden estar en diferentes niveles!). Un lenguaje de programación típico en XSLT es usar plantillas (de ahí la T en XSLT), que es programación declarativa, no imperativa (no le dices al procesador qué hacer, solo dices qué quieres que salga si se cumplen ciertas condiciones). Para este caso de uso, puede tener un aspecto similar al siguiente:
<!-- 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>
Esto funciona (con cualquier versión XSLT), porque la primera de arriba tiene una mayor prioridad (tiene un predicado). La plantilla de coincidencia "fall-through", la segunda, captura cualquier cosa que no sea válida. El tercero se encarga de generar el categoryName
valor de manera adecuada.
Tenga en cuenta que en este escenario no hay necesidad para que coincida con specifially categories
o category
, debido a que el procesador procesará automáticamente todos los niños, a menos que decimos que de otra forma (en este ejemplo, la segunda y la tercera plantilla No más trámite a los niños, porque no hay xsl:apply-templates
en ellos).
Este enfoque es más fácilmente extensible que el enfoque imperativo, ya que trata automáticamente con múltiples categorías y puede expandirse para otros elementos o excepciones simplemente agregando otra plantilla coincidente. Programación sin if-sucursales .
Nota: no existe tal cosa como null
en XML. Hay xsi: nil , pero rara vez se usa, especialmente en escenarios sin tipo sin un esquema de algún tipo.