web-dev-qa-db-fra.com

XSLT: puis-je déclarer une variable globalement et lui attribuer une valeur ultérieurement

Que puis-je faire pour que ce code fonctionne?

<xsl:choose>
  <xsl:when test='type = 6'>
    <xsl:variable name='title' select='root/info/title' />
  </xsl:when>
  <xsl:when test='type = 7'>
    <xsl:variable name='title' select='root/name' />
  </xsl:when>
  <xsl:otherwise>
    <xsl:variable name='title'>unknown</xsl:variable>
  </xsl:otherwise>
</xsl:choose>

<div class='title'>
  <xsl:value-of select='$title'/>
</div>

Cela ne fonctionne pas parce que quand je fais <xsl:value-of select='$title'/>, $title est hors de portée. J'ai essayé d'ajouter la ligne <xsl:variable name='title'/> en dehors de la portée, mais cela ne fonctionnera pas non plus, car quand j'appelle <xsl:variable name='title' select='root/info/title' /> par exemple, j'ai déjà défini cette variable auparavant. Comment dois-je résoudre ce problème?

23
Jules Colle

Vous pouvez déplacer le choix à l'intérieur du paramètre de la variable, comme ceci:

<xsl:variable name="title">
  <xsl:choose>
    <xsl:when test='type=6'>
      <xsl:value-of select="root/info/title" />
    </xsl:when>
    ...
  </xsl:choose>
</xsl:variable>

<div class='title'>
  <xsl:value-of select="$title" />
</div>
31
carols10cents
<xsl:choose> 
  <xsl:when test='type = 6'> 
    <xsl:variable name='title' select='root/info/title' /> 
  </xsl:when> 
  <xsl:when test='type = 7'> 
    <xsl:variable name='title' select='root/name' /> 
  </xsl:when> 
  <xsl:otherwise> 
    <xsl:variable name='title'>unknown</xsl:variable> 
  </xsl:otherwise> 
</xsl:choose> 

<div class='title'> 
  <xsl:value-of select='$title'/> 
</div> 

Ça ne marche pas

Ceci est une FAQ:

Vous définissez plusieurs variables, chacune nommée $title et chaque inutile, car il sort immédiatement de la portée.

La manière appropriée dans XSLT 1.0 pour définir une variable basée sur des conditions est:

<xsl:variable name="vTitle">
    <xsl:choose>
      <xsl:when test='type = 6'>
        <xsl:value-of select='root/info/title' />
      </xsl:when>
      <xsl:when test='type = 7'>
        <xsl:value-of  select='root/name' />
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="'unknown'"/>
      </xsl:otherwise>
    </xsl:choose>
</xsl:variable>

ne autre façon de définir la même variable: Dans ce cas particulier, vous voulez que la variable ait une valeur de chaîne. Cela peut s'exprimer sous une forme plus compacte:

<xsl:variable name="vTitle2" select=
"concat(root/info/title[current()/type=6],
        root/name[current()/type=7],
        substring('unknown', 1 div (type > 7 or not(type > 5)))
       )
"/>

Enfin, dans XSLT 2.0, on peut définir une telle variable encore plus commodément:

<xsl:variable name="vTitle3" as="xs:string" select=
 "if(type eq 6)
    then root/info/title
    else if(type eq 7)
            then root/name
            else 'unknown'
 "/>
14
Dimitre Novatchev

Vous ne pouvez pas réaffecter de variables dans XSLT (1.0). Le nom n'est probablement pas choisi par chance; une xsl:variable est plus un symbole qu'une variable.

Dans votre exemple, vous pouvez utiliser les éléments suivants:

<xsl:variable name='title'>
  <xsl:choose>
    <xsl:when test='type = 6'>
      <xsl:value-of select='root/info/title' />
    </xsl:when>
    <xsl:when test='type = 7'>
      <xsl:value-of select='root/name' />
    </xsl:when>
    <xsl:otherwise>
      <xsl:text>unknown</xsl:text>
    </xsl:otherwise>
  </xsl:choose>
</xsl:variable>
4
Dirk Vollmar

Outre la réponse standard de @ carolclarinet et la réponse plus compacte de @ Dimitre, lorsque le résultat dépend d'un nœud et que vous vous inquiétez de la réutilisation et de l'extensibilité, vous pouvez appliquer des modèles et utiliser la correspondance de modèle, à savoir:

<xsl:variable name="title"> 
    <xsl:apply-templates select="type" mode="title"/> 
</xsl:variable>

<xsl:template match="type[.=6]" mode="title"> 
    <xsl:value-of select='../root/info/title"/> 
</xsl:template> 
<xsl:template match="type[.=7]" mode="title"> 
    <xsl:value-of select='../root/name"/> 
</xsl:template> 
<xsl:template match="type" mode="title"> 
    <xsl:text>unknown</xsl:text> 
</xsl:template>
2
user357812