Respostas:
<xsl:call-template> é quase o equivalente a chamar uma função em uma linguagem de programação tradicional.
Você pode definir funções em XSLT, como este simples que produz uma string.
<xsl:template name="dosomething">
<xsl:text>A function that does something</xsl:text>
</xsl:template>
Esta função pode ser chamada via <xsl:call-template name="dosomething">.
<xsl:apply-templates>é um pouco diferente e nele está o verdadeiro poder do XSLT: ele pega qualquer número de nós XML (o que quer que você defina no selectatributo), os itera ( isso é importante: o apply-templates funciona como um loop! ) e encontra os modelos correspondentes para eles:
<!-- sample XML snippet -->
<xml>
<foo /><bar /><baz />
</xml>
<!-- sample XSLT snippet -->
<xsl:template match="xml">
<xsl:apply-templates select="*" /> <!-- three nodes selected here -->
</xsl:template>
<xsl:template match="foo"> <!-- will be called once -->
<xsl:text>foo element encountered</xsl:text>
</xsl:template>
<xsl:template match="*"> <!-- will be called twice -->
<xsl:text>other element countered</xsl:text>
</xsl:template>
Dessa forma, você cede um pouco de controle ao processador XSLT - não você decide para onde o fluxo do programa vai, mas o processador o faz encontrando a correspondência mais apropriada para o nó que está processando no momento.
Se vários modelos podem corresponder a um nó, aquele com a expressão de correspondência mais específica vence. Se houver mais de um modelo correspondente com a mesma especificidade, o declarado por último vence.
Você pode se concentrar mais no desenvolvimento de modelos e precisa de menos tempo para fazer o "encanamento". Seus programas se tornarão mais poderosos e modularizados, menos profundamente aninhados e mais rápidos (pois os processadores XSLT são otimizados para correspondência de modelos).
Um conceito a ser entendido com XSLT é o de "nó atual". Com <xsl:apply-templates>o nó atual, segue em frente com cada iteração, enquanto <xsl:call-template>não muda o nó atual. Ou seja, .dentro de um modelo chamado refere-se ao mesmo nó .do modelo de chamada. Este não é o caso com os modelos de aplicação.
Essa é a diferença básica. Existem alguns outros aspectos dos modelos que afetam seu comportamento: Seu modee priority, o fato de que os modelos podem ter tanto a namequanto a match. Também tem um impacto se o modelo foi importado ( <xsl:import>) ou não. Esses são usos avançados e você poderá lidar com eles quando chegar lá.
<xsl:apply-templates>se comporta como um loop. As diferenças de implementação na extremidade do processador XSLT não me afetarão como um programador XSLT, o resultado é absolutamente o mesmo para implementações paralelizadas e iterativas. Mas, para um novato em XSLT com um histórico imperativo, é útil imaginar <xsl:apply-templates>como uma espécie de loop for-each, mesmo que - tecnicamente - não seja.
Para adicionar à boa resposta de @Tomalak:
Aqui estão algumas diferenças importantes e não mencionadas :
xsl:apply-templatesé muito mais rico e profundo do que xsl:call-templatese até mesmo de xsl:for-each, simplesmente porque não sabemos qual código será aplicado nos nós da seleção - no caso geral, esse código será diferente para nós diferentes da lista de nós.
O código que será aplicado pode ser escrito bem depois que o xsl:apply templates foi escrito e por pessoas que não conhecem o autor original.
A implementação da biblioteca FXSL de funções de ordem superior (HOF) em XSLT não seria possível se XSLT não tivesse a <xsl:apply-templates>instrução.
Resumo : os modelos e a <xsl:apply-templates>instrução são como o XSLT implementa e lida com o polimorfismo.
Referência : Veja este tópico completo: http://www.biglist.com/lists/lists.mulberrytech.com/xsl-list/archives/200411/msg00546.html
xsl:apply-templatesé geralmente (mas não necessariamente) usado para processar todos ou um subconjunto de filhos do nó atual com todos os modelos aplicáveis. Isso suporta a recursividade do aplicativo XSLT que está correspondendo à (possível) recursividade do XML processado.
xsl:call-templatepor outro lado, é muito mais parecido com uma chamada de função normal. Você executa exatamente um modelo (nomeado), geralmente com um ou mais parâmetros.
Então, eu uso xsl:apply-templatesse quero interceptar o processamento de um nó interessante e (geralmente) injetar algo no fluxo de saída. Um exemplo típico (simplificado) seria
<xsl:template match="foo">
<bar>
<xsl:apply-templates/>
</bar>
</xsl:template>
enquanto com xsl:call-templateeu normalmente resolvo problemas como adicionar o texto de alguns subnós juntos, transformar conjuntos de nós selecionados em texto ou outros conjuntos de nós e semelhantes - qualquer coisa para a qual você escreveria uma função especializada reutilizável.
Como uma observação adicional ao texto de sua pergunta específica:
<xsl:call-template name="nodes"/>
Isso chama um modelo chamado 'nós':
<xsl:template name="nodes">...</xsl:template>
Esta é uma semântica diferente de:
<xsl:apply-templates select="nodes"/>
... que aplica todos os modelos a todos os filhos de seu nó XML atual cujo nome é 'nós'.
A funcionalidade é de fato semelhante (além da semântica de chamada, onde call-templaterequer um nameatributo e um modelo de nomes correspondente).
No entanto, o analisador não será executado da mesma maneira.
Do MSDN :
Ao contrário
<xsl:apply-templates>,<xsl:call-template>não altera o nó atual ou a lista de nós atual.
<xsl:apply-templates>deva ser implementada como um loop - pelo contrário, ela pode ser implementada em paralelo, porque as diferentes aplicações nos diferentes nós da lista de nós são absolutamente independentes umas das outras.