Как указано в спецификации:
В отсутствие атрибута select инструкция xsl: apply-templates обрабатывает все дочерние элементы текущего узла, включая текстовые узлы.
apply-templates
без выбора XPath, применяет шаблоны в соответствии с иерархией представления дерева XML, созданного процессором во время компиляции, если вы явно не управляете шаблонами (как вы делали для title
и artist
).
Вы также можете подумать о том, как встроенные правила шаблонов работают.Эти правила работают негласно и позволяют рекурсивному процессу продолжаться в случае отсутствия успешного сопоставления с шаблоном.
Так что, если вы пропустите совпадение с шаблоном для корня /
, ваши шаблоны будут выполняться в любом случае, благодаря встроенному-in правила.
Я думаю, что порядок обработки должен быть таким:
- Шаблон соответствует корню, а
xsl:apply-templates
говорит процессору применить шаблоны к catalog
element (в том месте, где он вызывается). - Не найдено подходящих шаблонов для
catalog
, так что встроенное правило позволяет продолжать обработку в отношении других элементов-потомков (catalog
) до тех пор, покаНайден новый шаблон с удачным совпадением с образцом (cd
)
Встроенное правило работает за кулисами, и вы всегда должны думать, что ваше преобразование составлено вашими шаблонами, плюс несколько дополнительных скрытых (но работает) шаблоны:
<xsl:template match="*|/">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="text()|@*">
<xsl:value-of select="."/>
</xsl:template>
<xsl:template match="processing-instruction()|comment()"/>
В вашем конкретном случае первый из трех приведенных выше шаблонов был ответственным за применениешаблоны для элементов cd
.
Эти встроенные шаблоны переопределяются каждый раз, когда вы пишете явный шаблон.
Примеры
Вы можете получить то же самое, заменив:
<xsl:template match="cd">
<p>
<xsl:apply-templates select="title"/>
<xsl:apply-templates select="artist"/>
</p>
</xsl:template>
на:
<xsl:template match="country|company|price|year"/>
<xsl:template match="cd">
<p>
<xsl:apply-templates />
</p>
</xsl:template>
О корне, в вашем случае, вы также можете получить то же самое, заменив:
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
с
<xsl:template match="/catalog">
<html>
<body>
<h2>My CD Collection</h2>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
или все еще:
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<xsl:apply-templates select="catalog"/>
</body>
</html>
</xsl:template>
или все еще:
<xsl:template match="catalog">
<html>
<body>
<h2>My CD Collection</h2>
<xsl:apply-templates />
</body>
</html>
</xsl:template>