template - xslt tutorial




XSLT xsl: séquence. À quoi ça sert..? (3)

Je sais que la question suivante est un peu débutante mais j'ai besoin de votre aide pour comprendre un concept de base.

Je voudrais d'abord dire que je suis un programmeur XSLT depuis 3 ans et pourtant, il y a des choses nouvelles et très basiques que j'ai apprises ici que je n'ai jamais connues (dans mon travail, quelqu'un apprend à programmer seul, il n'y a pas de cours) impliqué).

Ma question est la suivante: quelle est l’utilisation de xsl:sequence ?

J'ai utilisé xsl:copy-of pour copier le nœud tel xsl:apply-templates , xsl:apply-templates afin de modifier les nœuds que j'ai sélectionnés et la value-of texte simple.

Je n'ai jamais eu la nécessité d'utiliser xsl:sequence . J'apprécierais si quelqu'un peut me montrer un exemple d'utilisation de xsl:sequence qui est préféré ou ne peut pas être réalisé sans ceux que j'ai notés ci-dessus.

Encore une chose, bien sûr, j'ai lu à propos de la définition de xsl:sequence , mais je ne pouvais pas en déduire l'utilité.


Eh bien, pour renvoyer une valeur d'un certain type, vous utilisez xsl:sequence tant que xsl:value-of dépit de son nom crée toujours un nœud de texte (depuis XSLT 1.0). Donc, dans un corps de fonction que vous utilisez

  <xsl:sequence select="42"/>

pour renvoyer une valeur xs:integer , vous utiliseriez

<xsl:sequence select="'foo'"/>

pour renvoyer une valeur xs:string et

<xsl:sequence select="xs:date('2013-01-16')"/>

pour renvoyer une valeur xs:date , etc. Bien sûr, vous pouvez également renvoyer des séquences avec par exemple <xsl:sequence select="1, 2, 3"/> .

À mon avis, vous ne voudriez pas créer un nœud de texte ou même un nœud d'élément car il est inefficace.

Voilà donc ce que je veux dire, avec le nouveau système de type basé sur un schéma de XSLT et XPath 2.0, un moyen est nécessaire pour retourner ou faire circuler des valeurs de ces types et une nouvelle construction était nécessaire.

Michael Kay dit dans son "XSLT 2.0 et XPath 2.0 de référence du programmeur" à propos de xsl:sequence : "Cette instruction innocente introduite dans XSLT 2.0 a des effets considérables sur la capacité du langage XSLT, car cela signifie que les instructions XSLT et Les constructeurs de séquences (et donc les fonctions et les modèles) sont capables de renvoyer toute valeur autorisée par le modèle de données XPath, sans quoi les instructions XSLT ne peuvent être utilisées que pour créer de nouveaux nœuds dans un arbre de résultat. et références aux nœuds existants. ".


Le cas d'utilisation le plus courant pour xsl: sequence est de renvoyer un résultat à partir de xsl: function.

<xsl:function name="f:get-customers">
  <xsl:sequence select="$input-doc//customer"/>
</xsl:function>

Mais il peut aussi être utile dans d'autres contextes, par exemple

<xsl:variable name="x" as="element()*">
  <xsl:choose>
    <xsl:when test="$something">
       <xsl:sequence select="//customer"/>
    </xsl:when>
    <xsl:otherwise>
       <xsl:sequence select="//supplier"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:variable>

L'essentiel ici est qu'il renvoie des références aux nœuds d'origine, il ne fait pas de nouvelles copies.


<xsl:sequence> sur une valeur atomique (ou une séquence de valeurs atomiques) est la même que <xsl:copy-of> deux renvoient simplement une copie de leur entrée. La différence vient lorsque vous considérez des nœuds.

Si $ n est un nœud à élément unique, par exemple comme défini par quelque chose comme

<xsl:variable name="n" select="/html"/>

alors

<xsl:copy-of select="$n"/>

Renvoie une copie du noeud, il a le même nom et la même structure enfant mais il s'agit d'un nouveau noeud avec une nouvelle identité (et aucun parent).

<xsl:sequence select="$n"/>

Renvoie le nœud $ n. Le nœud retourné a le même parent que $ n et lui est égal par l'opérateur is Xpath.

La différence est presque entièrement masquée dans l’utilisation des modèles traditionnels (style XSLT 1) car vous n’obtenez jamais accès au résultat de l’une ou de l’autre opération, le résultat du constructeur étant implicitement copié dans l’arbre de sortie. la copie est masquée.

<xsl:template match="a">
   <x>
   <xsl:sequence select="$n"/>
   </x>
</xsl:template>

est le même que

<xsl:template match="a">
    <x>
    <xsl:copy-of select="$n"/>
    </x>
</xsl:template>

Les deux créent un nouveau nœud d'élément et copient le résultat du contenu en tant qu'enfants du nouveau nœud x .

Cependant, la différence est rapidement visible si vous utilisez des fonctions.

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:f="data:,f">

    <xsl:variable name="s">
        <x>hello</x>
    </xsl:variable>

    <xsl:template name="main">
        ::
        :: <xsl:value-of select="$s/x is f:s($s/x)"/>
        :: <xsl:value-of select="$s/x is f:c($s/x)"/>
        ::
        :: <xsl:value-of select="count(f:s($s/x)/..)"/>
        :: <xsl:value-of select="count(f:c($s/x)/..)"/>
        ::
    </xsl:template>

    <xsl:function name="f:s">
        <xsl:param name="x"/>
        <xsl:sequence select="$x"/>
    </xsl:function>

    <xsl:function name="f:c">
        <xsl:param name="x"/>
        <xsl:copy-of select="$x"/>
    </xsl:function>

</xsl:stylesheet>

Produit

$ saxon9 -it main seq.xsl
<?xml version="1.0" encoding="UTF-8"?>
::
:: true
:: false
::
:: 1
:: 0
::

Ici, les résultats de xsl:sequence et xsl:copy-of sont radicalement différents.





xslt-2.0