Я знаю, что этот вопрос старый, но между всеми ответами мне не хватает одного, который является общим подходом для этого варианта использования при разработке XSLT.
Я представляю, что отсутствующий код из OP выглядит примерно так:
<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>
И что вход выглядит примерно так:
<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>
Т.е. я предполагаю, что может быть ноль, пустой, один или несколько categoryName
элементов. Чтобы справиться со всеми этими случаями, использование xsl:choose
конструкций -style или, другими словами, обязательно, быстро становится беспорядочным (тем более, если элементы могут быть на разных уровнях!). Типичная идиома программирования в XSLT - использование шаблонов (отсюда и T в XSLT), что является декларативным программированием, а не императивом (вы не указываете процессору, что делать, вы просто указываете, что вы хотите выводить, если выполняются определенные условия). Для этого варианта использования это может выглядеть примерно так:
<!-- 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>
Это работает (с любой версией XSLT), потому что первая выше имеет более высокий приоритет (у нее есть предикат). Второй шаблон сопоставления «проваливается», перехватывает все, что недопустимо. Третий затем заботится о categoryName
правильном выводе значения.
Обратите внимание , что в этом случае нет необходимости в особенности по сопрягать categories
или category
, потому что процессор будет автоматически обрабатывать все дети, если не сказать ему , в противном случае (в этом примере, второй и третий шаблон не дальнейший процесс детей, потому что нет xsl:apply-templates
в их).
Этот подход легче расширить, чем императивный, поскольку он автоматически работает с несколькими категориями и может быть расширен для других элементов или исключений, просто добавив другой соответствующий шаблон. Программирование без if-веток .
Примечание: null
в XML нет такой вещи . Существует xsi: nil , но он используется редко, особенно редко в нетипизированных сценариях без какой-либо схемы.