2010-12-12 30 views
7

Je voulais utiliser un nom de variable dynamique dans l'instruction select de xslt.pouvons-nous utiliser le nom de variable dynamique dans l'instruction select dans xslt?

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:template match="/"> 
    <xsl:variable name="input" select="input/message" /> 
    <xsl:variable name="Name" select="'MyName'" /> 
    <xsl:variable name="Address" select="MyAddress" /> 
    <xsl:variable name="output" select="concat('$','$input')" /> <!-- This is not working --> 
    <output> 
     <xsl:value-of select="$output" /> 
    </output> 
</xsl:template> 

Les valeurs possibles pour la variable "entrée" est 'Nom' ou 'Adresse'. L'instruction select de la variable de sortie doit avoir un nom de variable dynamique basé sur la valeur de la variable d'entrée. Je ne veux pas utiliser xsl: choisissez. Je voulais sélectionner la valeur de manière dynamique. S'il vous plaît, donnez-moi une solution.

Merci, dhinu

+0

bonne question, +1. Voir ma réponse pour une solution complète et courte. :) –

Répondre

11

XSLT 1.0 et XSLT 2.0 ne sont pas l'évaluation dynamique.

solution à votre problème:

Cette transformation:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:my="my:my"> 
<xsl:output method="text"/> 

<my:values> 
    <name>MyName</name> 
    <address>MyAdress</address> 
</my:values> 

<xsl:template match="/"> 
    <xsl:variable name="vSelector" 
    select="input/message"/> 
    <xsl:value-of select= 
    "document('')/*/my:values/*[name()=$vSelector]"/> 
</xsl:template> 
</xsl:stylesheet> 

lorsqu'il est appliqué sur le document XML suivant:

<input> 
    <message>address</message> 
</input> 

produit le voulu, résultat correct:

MyAdress 

lorsque la même transformation est appliquée sur ce document XML:

<input> 
    <message>name</message> 
</input> 

à nouveau le résultat recherché, correct est produit:

MyName 

Enfin: Si vous ne souhaite pas utiliser la fonction document(), mais utiliserait la fonction d'extension xxx:node-set(), alors cette solution (très similaire) est ce que vous voulez, où vous pouvez consulter votre documentation XSLTprocessor pour l'espace de noms exact de l'extension:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:ext="http://exslt.org/common" > 
<xsl:output method="text"/> 

<xsl:variable name="vValues"> 
    <name>MyName</name> 
    <address>MyAdress</address> 
</xsl:variable> 

<xsl:template match="/"> 
    <xsl:variable name="vSelector" 
    select="input/message"/> 
    <xsl:value-of select= 
    "ext:node-set($vValues)/*[name()=$vSelector]"/> 
</xsl:template> 
</xsl:stylesheet> 
+0

Merci! Cela a fonctionné pour moi .. Je veux juste savoir s'il y a une autre manière sans utiliser l'espace de noms supplémentaire xmlns: my = "my: my"? – dhinu

+0

@dhinu: Content que ma réponse ait été utile. À SO, la gratitude est exprimée en acceptant la réponse (en cliquant sur la coche à côté de la réponse) :). Vous pouvez mettre le '' dans un autre fichier et y accéder à nouveau avec la fonction 'document()'. Dans XSLT 1.0, vous devez généralement utiliser cette technique. Si les éléments sont dans le corps d'un 'ou d'un' ', ils ne peuvent pas être accédés en utilisant XPath directement et une fonction d'extension (' xxx: node-set() ') doit être appliquée en premier . Dans XSLT 2.0, les éléments à l'intérieur d'un '' ou d'un '' sont directement accessibles. –

+0

Pouvez-vous donner un exemple pour accéder aux éléments dans le corps d'une variable xsl: en utilisant la fonction d'extension (xxx: node-set())? (Im en utilisant XSLT 1.0) – dhinu

0

côté @ bonne réponse de Dimitre, pour ce cas particulier (valeur de chaîne de sortie), vous pouvez également utiliser:

<xsl:variable name="output" 
       select="concat(substring($Name, 1 div ($input = 'Name')), 
          substring($Address, 1 div ($input = 'Address')))"/>