Часто бывает нужно применить шаблон для элемента только если этот элемент (или его содержимое) удовлетворяет некоторому условию. Простой пример: применить шаблон для элемента <Brands> если внутри есть хотя бы один элемент <Brand>. Рассмотрим несколько вариантов как можно сделать эту проверку.
Вариант 1
<xsl:template match="Something">
<xsl:if test="Brands/Brand">
<xsl:apply-templates select="Brands"/>
</xsl:if>
</xsl:template>
<xsl:template match="Brands">
<h2>Производители</h2>
<ul>
<xsl:apply-templates select="Brand"/>
</ul>
</xsl:template>
Неудачное решение, поскольку, написав проверку в шаблоне для <Something>, мы поместили в этот шаблон знание об особенности трансформации <Brands>.
Вариант 2
<xsl:template match="Something">
<xsl:apply-templates select="Brands[Brand]"/>
</xsl:template>
<xsl:template match="Brands">
<h2>Производители</h2>
<ul>
<xsl:apply-templates select="Brand"/>
</ul>
</xsl:template>
Немного компактнее, но проблема первого варианта осталась.
Вариант 3
<xsl:template match="Something">
<xsl:apply-templates select="Brands"/>
</xsl:template>
<xsl:template match="Brands">
<xsl:if test="Brand">
<h2>Производители</h2>
<ul>
<xsl:apply-templates select="Brand"/>
</ul>
</xsl:if>
</xsl:template>
Гораздо лучше. Шаблон для <Something> просто вызывает шаблон для <Brands>, не заморачиваясь о внутреннем устройстве <Brands>. Шаблон для <Brands> сам разбирается как трансформировать <Brands>.
Вариант 4
<xsl:template match="Something">
<xsl:apply-templates select="Brands"/>
</xsl:template>
<xsl:template match="Brands"/>
<xsl:template match="Brands[Brand]">
<h2>Производители</h2>
<ul>
<xsl:apply-templates select="Brand"/>
</ul>
</xsl:template>
Я предпочитаю этот вариант. Он также хорошо работает и в случае с несколькими условиями — вместо громоздкого <xsl:choose> мы получаем компактные шаблончики.
<xsl:template match="Brands"/>
<xsl:template match="Brands[Brand]">
<h2>Производители</h2>
<ul>
<xsl:apply-templates select="Brand"/>
</ul>
</xsl:template>
<xsl:template match="Brands[count(Brand) > 10]">
<h2>Много производителей</h2>
<!-- Выводим бренды в три колонки -->
</xsl:template>