web-dev-qa-db-fra.com

Quelles sont les différences entre 'call-template' et 'apply-templates' en XSL?

Je suis nouveau dans XSLT, donc je suis un peu confus au sujet des deux balises,

<xsl:apply-templates name="nodes">

et

<xsl:call-template select="nodes"> 

Alors pouvez-vous énumérer la différence entre eux?

114
Venkat

<xsl:call-template> est un équivalent proche de l'appel d'une fonction dans un langage de programmation traditionnel.

Vous pouvez définir des fonctions dans XSLT, comme ce simple qui génère une chaîne.

<xsl:template name="dosomething">
  <xsl:text>A function that does something</xsl:text>
</xsl:template>

Cette fonction peut être appelée via <xsl:call-template name="dosomething">.

<xsl:apply-templates> est un peu différent et réside dans le pouvoir réel de XSLT: il faut un nombre quelconque de nœuds XML (tout ce que vous définissez dans l'attribut select), puis les itère (il est important: -templates fonctionne comme une boucle!) et trouve les modèles correspondants pour eux:

<!-- 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>

De cette façon, vous laissez un peu de contrôle au processeur XSLT - vous ne décidez pas où le flux du programme va aller, mais le processeur le fait en trouvant la correspondance la plus appropriée pour le nœud en cours de traitement.

Si plusieurs modèles peuvent correspondre à un nœud, celui avec l'expression de correspondance la plus spécifique l'emporte. S'il existe plus d'un modèle correspondant avec la même spécificité, celui déclaré en dernier l'emporte.

Vous pouvez vous concentrer davantage sur l'élaboration de modèles et prendre moins de temps pour effectuer la "plomberie". Vos programmes deviendront plus puissants et modularisés, moins imbriqués et plus rapides (car les processeurs XSLT sont optimisés pour la correspondance des modèles).

Un concept à comprendre avec XSLT est celui du "nœud actuel". Avec <xsl:apply-templates> le nœud actuel continue à chaque itération, alors que <xsl:call-template> ne change pas le noeud actuel. C'est à dire. le . dans un modèle appelé fait référence au même noeud que le . dans le modèle d'appel. Ce n'est pas le cas avec apply-templates.

C'est la différence fondamentale. D'autres aspects des modèles affectent leur comportement: mode et priority, le fait que les modèles puissent avoir à la fois un name et un match. Le fait que le modèle ait été importé a également une incidence (<xsl:import>) ou pas. Ce sont des utilisations avancées et vous pouvez les gérer quand vous y arrivez.

155
Tomalak

Pour ajouter à la bonne réponse de @Tomalak:

Voici quelques différences importantes et non mentionnées :

  1. xsl:apply-templates est beaucoup plus riche et profond que xsl:call-templates et même de xsl:for-each, simplement parce que nous ne savons pas quel code sera appliqué aux noeuds de la sélection - dans le cas général, ce code sera différent pour différents noeuds de la liste de noeuds.

  2. Le code qui sera appliqué peut être écrit après le xsl:apply templates a été écrit et par des personnes qui ne connaissent pas l'auteur original.

La mise en œuvre de bibliothèque FXSL de fonctions d'ordre supérieur (HOF) dans XSLT ne serait pas possible si XSLT n'a pas ' t ont le <xsl:apply-templates> instruction.

Résumé : Modèles et le <xsl:apply-templates> instruction est la façon dont XSLT implémente et gère le polymorphisme.

Référence : Voir le fil entier: http://www.biglist.com/lists/ lists.mulberrytech.com/xsl-list/archives/200411/msg00546.html

15
Dimitre Novatchev

xsl:apply-templates est généralement (mais pas nécessairement) utilisé pour traiter la totalité ou un sous-ensemble d'enfants du nœud actuel avec tous modèles applicables. Cela prend en charge la récursivité de l'application XSLT qui correspond à la récursivité (possible) du fichier XML traité.

xsl:call-template, par contre, ressemble beaucoup plus à un appel de fonction normal. Vous exécutez exactement un modèle (nommé), généralement avec un ou plusieurs paramètres.

Donc j'utilise xsl:apply-templates _ si je veux intercepter le traitement d’un nœud intéressant et (généralement) injecter quelque chose dans le flux de sortie. Un exemple typique (simplifié) serait

<xsl:template match="foo">
  <bar>
    <xsl:apply-templates/>
  </bar>
</xsl:template>

alors qu'avec xsl:call-template Je résous généralement des problèmes tels que l’addition simultanée du texte de certains sous-nœuds, la transformation de jeux de nœuds sélectionnés en texte ou en d’autres jeux de nœuds, etc.

Modifier:

En guise de remarque complémentaire au texte de votre question spécifique:

<xsl:call-template name="nodes"/> 

Cela appelle un modèle nommé 'nœuds':

    <xsl:template name="nodes">...</xsl:template>

Ceci est une sémantique différente de:

<xsl:apply-templates select="nodes"/>

... qui applique tous les modèles à tous les enfants de votre nœud XML actuel dont le nom est "nœuds".

7
TToni

La fonctionnalité est en effet similaire (mis à part la sémantique de l'appel, où call-template nécessite un attribut name et un modèle de noms correspondant).

Cependant, l'analyseur ne s'exécutera pas de la même manière.

De MSDN :

Contrairement à <xsl:apply-templates>, <xsl:call-template> ne change pas le noeud actuel ni la liste des noeuds actuels.

2
Oded