2009-01-15 5 views
5

Je passe dans un tas de paires clé-valeur en tant que paramètres à un XSL (date -> "20 Janvier", auteur -> "Dominic Rodger", ...).Variables dynamiques dans XSLT

Ceux-ci sont référencés en XML j'analyse - XML ​​ressemble à ceci:

<element datasource="date" /> 

À l'heure actuelle, je ne peux pas travailler comment obtenir Janvier 20e sur ces sauf horrible <xsl:choose> déclaration:

<xsl:template match="element"> 
    <xsl:choose> 
    <xsl:when test="@datasource = 'author'"> 
     <xsl:value-of select="$author" /> 
    </xsl:when> 
    <xsl:when test="@datasource = 'date'"> 
     <xsl:value-of select="$date" /> 
    </xsl:when> 
    ... 
    </xsl:choose> 
</xsl:template> 

Je voudrais utiliser quelque chose comme:

<xsl:template match="element"> 
    <xsl:value-of select="${@datasource}" /> 
</xsl:template> 

Mais je suppose que ce n'est pas possible. J'ouvre à l'aide d'appels de fonction externes, mais je veux éviter d'avoir à énumérer toutes les clés de carte possibles dans mon XSL. Des idées?

Merci,

Dom

+0

S'il vous plaît, ne noter que les trois réponses présentées, deux ne sont pas correctes - il n'y a pas un opérateur « + » pour les chaînes en XPath, et aussi, un AVT ne peut pas être spécifiée pour un « select » attribut dans XSLT. Ma solution est testée et fonctionne. –

Répondre

2

Voici une solution possible, mais je vous recommande de regrouper tous les paramètres dans un fichier XML distinct et les accès à la fonction document():

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

<xsl:param name="date" select="'01-15-2009'"/> 
<xsl:param name="author" select="'Dominic Rodger'"/> 
<xsl:param name="place" select="'Hawaii'"/> 
<xsl:param name="time" select="'midnight'"/> 

<xsl:variable name="vrtfParams"> 
    <date><xsl:value-of select="$date"/></date> 
    <author><xsl:value-of select="$author"/></author> 
    <place><xsl:value-of select="$place"/></place> 
    <time><xsl:value-of select="$time"/></time> 
</xsl:variable> 

<xsl:variable name="vParams" select="ext:node-set($vrtfParams)"/> 

    <xsl:template match="element"> 
     <xsl:value-of select= 
     "concat('&#xA;', @datasource, ' = ', 
       $vParams/*[name() = current()/@datasource] 
       )" 
     /> 
    </xsl:template> 
</xsl:stylesheet> 

Lorsque cette transformation est appliquée sur le code XML suivant Document:

<data> 
    <element datasource="date" /> 
    <element datasource="place" /> 
</data> 

est produit le résultat correct:

date = 01-15-2009

place = Hawaii

Do noter l'utilisation de la fonction xxx:node-set() (the EXSLT one est utilisé ici) pour convertir un fichier RTF (Result Tree Fragment) à un document xml régulier (temporaire arbre).

-2

Que diriez-vous

<xsl:template match="date-element"> 
    <xsl:text>${date}</xsl:text> 
</xsl:template> 

dire au lieu d'utiliser un attribut, correspondance en utilisant différents noms d'éléments.

Si vous ne pouvez pas modifier le code source, exécutez-le via un petit fichier XSLT qui convertit les attributs en noms d'éléments corrects.

Une solution différente consisterait à placer les éléments xsl: param dans un document XML différent (ou essayer de faire se relire le modèle XSLT). Ensuite, vous pouvez utiliser xsl: key et key() pour les référencer.

[EDIT] Remplacé xsl: valeur-de avec xsl: texte. Je n'ai pas d'utilitaire XSLT à portée de main, donc je ne peux pas tester cela. S'il vous plaît poster un commentaire si cela ne fonctionne pas non plus.

+0

Désolé, mais l'attribut "select" est le seul pour lequel les AVT (Attribute-value-templates) ne peuvent pas être spécifiés. –

0

Si votre @datasource correspond toujours au nom du paramètre, vous pouvez essayer la fonction "evaluate". Remarque: ce code n'a pas été testé.

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:exslt-dynamic="http://exslt.org/dynamic" 
> 

<xsl:param name="date"/> 

<xsl:template match="element"> 
    <xsl:value-of select="exslt-dynamic:evaluate('$' + @datasource)"/> 
</xsl:template> 

</xsl:stylesheet> 
+1

Il n'a pas été testé, en effet. En XPath, on ne peut pas additionner les chaînes '+' - cela ne compilerait même jamais. –