Wiem, że to pytanie jest stare, ale między wszystkimi odpowiedziami brakuje mi jednego, które jest powszechnym podejściem do tego przypadku użycia w rozwoju XSLT.
Wyobrażam sobie, że brakujący kod z OP wygląda mniej więcej tak:
<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>
I że dane wejściowe wyglądają mniej więcej tak:
<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>
Tzn. Zakładam, że może być zero, pusty, pojedynczy lub wiele categoryNameelementów. Aby poradzić sobie z tymi wszystkimi przypadkami za pomocą xsl:choosekonstruktów-style, lub innymi słowy, koniecznie szybko robi się bałagan (tym bardziej, jeśli elementy mogą znajdować się na różnych poziomach!). Typowym idiomem programistycznym w XSLT jest używanie szablonów (stąd T w XSLT), co jest programowaniem deklaratywnym, a nie koniecznym (nie mówisz procesorowi, co ma robić, po prostu mówisz, co chcesz uzyskać, jeśli spełnione są określone warunki). W tym przypadku użycia może to wyglądać mniej więcej tak:
<!-- 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>
Działa to (z każdą wersją XSLT), ponieważ pierwsza powyżej ma wyższy priorytet (ma predykat). Drugi szablon dopasowania „przechodzący” łapie wszystko, co nie jest prawidłowe. Trzeci zadba następnie categoryNameo prawidłowe wyprowadzenie wartości.
Należy zauważyć, że w tym scenariuszu nie ma potrzeby, aby specifially dopasować categorieslub category, ponieważ procesor będzie automatycznie przetwarzać wszystkie dzieci, chyba że mówimy to inaczej (w tym przykładzie, drugi i trzeci szablon nie dalej przetwarzać dzieci, bo nie ma xsl:apply-templatesw im).
To podejście jest łatwiejsze do rozszerzenia niż podejście imperatywne, ponieważ automatycznie zajmuje się wieloma kategoriami i można je rozszerzyć o inne elementy lub wyjątki, po prostu dodając inny pasujący szablon. Programowanie bez rozgałęzień if .
Uwaga: nie ma czegoś takiego jak nullw XML. Istnieje xsi: zero , ale jest to rzadko używane, szczególnie rzadko w nietypowych scenariuszach bez jakiegoś schematu.