0 votes

Ordre d'exécution dans la feuille de style xslt

Disons que j'ai une feuille de style xslt comme la suivante :

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:exslt="http://exslt.org/common"
    exclude-result-prefixes="exslt"
    version="1.0">

<xsl:output method="html" encoding="utf-8" indent="no" />
<xsl:variable name="foo" value="'foo'" />
<xsl:variable name="bar" value="'bar'" />

</xsl:stylesheet>

Quel est l'ordre d'exécution ? Est-il garanti que la variable globale $foo sera évaluée avant la variable globale $bar ? (Si cela dépend du moteur de traitement, j'utilise libxslt).

3voto

Pavel Minaev Points 60647

L'ordre d'évaluation n'est, en général, pas garanti, sauf lorsque de telles garanties découlent de la dépendance des expressions. Par exemple, l'ordre d'évaluation n'est pas garanti :

<xsl:variable name="foo" value="123" />

<xsl:variable name="bar" value="456" />

<xsl:variable name="baz" value="$foo + $bar" />

<xsl:variable name="dummy" value="42 div 0" />

<xsl:template match="/">
  <xsl:value-of select="$baz"/>
</xsl:template>

Ici, il est certain que baz sera évaluée à un moment donné avant d'être émise - peut-être juste avant d'être émise, peut-être au démarrage, peut-être quelque part entre les deux - et cette foo y bar sera évaluée avant baz - mais l'ordre relatif d'évaluation des foo y bar n'est pas défini.

dummy est un cas intéressant. Il n'est utilisé nulle part et pourrait donc être complètement omis, mais, si ma compréhension de la spécification est correcte, le processeur doit néanmoins soulever une erreur comme s'il avait été évalué. Le moment où il le fait n'est pas important, car il n'y a aucun moyen de le savoir à l'intérieur de XSLT - donc dummy sera évaluée à un moment indéterminé de l'exécution (ce peut être la première chose qu'elle fait, ou la dernière après que toutes les sorties ont déjà été générées), mais il est garanti que la transformation échouera avec une erreur.

Tout cela concerne XSLT et XPath 1.0. Dans la version 2.0, la situation est plus souple - l'évaluation n'est même pas obligatoire ; si le processeur peut obtenir un résultat valide en ignorant l'évaluation de certaines expressions qui, sinon, entraîneraient une erreur, il a l'autorisation générale de le faire.

0voto

ChaosPandion Points 37025

D'après mon expérience, les variables sont toujours disponibles lorsque les modèles sont exécutés. En fait, j'ai traité des modèles basés sur des variables en dehors des modèles.

0voto

Mark Elliot Points 31871

À l'intérieur d'un modèle, les définitions de variables s'exécutent dans l'ordre de haut en bas ( foo puis bar )

Editer [déclaration incorrecte supprimée] : Comme l'explique Pavel aquí Dans ce cas, XSLT a un comportement bien défini qui stipule comment les variables seront évaluées. En particulier, les cas de test suivants illustrent le comportement que vous demandez.

Un bon cas de test pourrait être de faire dépendre une variable de l'autre...par exemple

<xsl:variable name="foo" select="'foo'" />
<xsl:variable name="bar" select="$foo" />

Ensuite, il est possible d'imprimer les variables à l'écran.

L'ordre peut également être inversé (par exemple)

<xsl:variable name="bar" select="$foo" />
<xsl:variable name="foo" select="'foo'" />

Pour ce que ça vaut, je pense que vous voulez dire select où vous avez écrit value dans votre message.

Édition 1 : Puisque les variables en XSLT sont immuables et que l'exécution de fonctions ne peut pas avoir d'effets secondaires l'ordre ne devrait pas avoir d'importance. En particulier, la seule situation où l'ordre importe est celle de mon illustration simple (que vous devriez tester pour vous en assurer) où une variable dépend de la valeur d'une autre.

Edit 2 : correction d'une erreur dans l'exemple "code".

-1voto

Joy Dutta Points 2295

Je travaille avec ajitomatix sur ce problème et le vrai problème est le suivant : nous avons un tas de déclarations de variables en dehors de tout modèle, après une initialisation :

<xsl:variable name="ignore" select="fun_init(args)" />
<xsl:variable name="foo1" select="fun('foo1')" />
<xsl:variable name="foo2" select="fun('foo2')" />
<xsl:variable name="foo3" select="fun('foo3')" />
...

La fonction fun() ne donnera le bon résultat que si l'on s'assure que la fonction init a été appelée avant. Mais grâce à des points d'arrêt dans gdb, je constate que l'ordre est presque aléatoire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X