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 categoryName
elementów. Aby poradzić sobie z tymi wszystkimi przypadkami za pomocą xsl:choose
konstruktó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 categoryName
o prawidłowe wyprowadzenie wartości.
Należy zauważyć, że w tym scenariuszu nie ma potrzeby, aby specifially dopasować categories
lub 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-templates
w 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 null
w XML. Istnieje xsi: zero , ale jest to rzadko używane, szczególnie rzadko w nietypowych scenariuszach bez jakiegoś schematu.