2009-02-26 5 views
6

Je trouve qu'il est impossible d'utiliser with-param pour travailler avec apply-templates. À titre d'exemple, j'ai piraté les exemples donnés dans w3schools.Pourquoi ne puis-je pas obtenir les paramètres pour travailler avec apply-templates dans XSL?

xsl

<xsl:template match="/"> 
    <xsl:apply-templates> 
    <xsl:with-param name="test" select="'has this parameter been passed?'"/> 
    </xsl:apply-templates> 
</xsl:template> 

<xsl:template match="cd"> 
    <xsl:param name="test"></xsl:param> 
    parameter: 
    <xsl:value-of select="$test"></xsl:value-of> 
</xsl:template> 

xml

<catalog> 
    <cd> 
    <title>Empire Burlesque</title> 
    <artist>Bob Dylan</artist> 
    <country>USA</country> 
    <company>Columbia</company> 
    <price>10.90</price> 
    <year>1985</year> 
    </cd> 
    <cd> 
    <title>Hide your heart</title> 
    <artist>Bonnie Tyler</artist> 
    <country>UK</country> 
    <company>CBS Records</company> 
    <price>9.90</price> 
    <year>1988</year> 
    </cd> 
</catalog> 

(Si tout va bien), vous verrez que le paramètre de test n'est pas passé au modèle de cd. Je peux le faire fonctionner quand j'utilise un template d'appel, mais pas des templates d'application. Que se passe-t-il? J'utilise XSL 1.0. S'il vous plaît ignorer le fait que je passe un paramètre codé en dur - ce n'est qu'un exemple.

Répondre

5

Hmmm ... intéressant ... tombe en panne pour moi en utilisant XslTransform et XslCompiledTransform dans .NET - mais il ressemble à devrait travail ... curieux ...

mise à jour le problème voitm être le racine match; essayer

<xsl:template match="/catalog"> <!-- CHANGE HERE --> 
    <xsl:apply-templates> 
    <xsl:with-param name="test" select="'has this parameter been passed?'"/> 
    </xsl:apply-templates> 
</xsl:template> 

Cela fonctionne alors pour moi sans aucun autre changement. La différence est que vous correspondiez au nœud racine. Lorsque vous avez fait vos "modèles d'application", il a cascadé d'abord pour cataloguer (avec les paramètres), puis pour cd (sans les paramètres). Pour obtenir ce que vous voulez, vous devez commencer au catalogue. Vous pouvez le voir en ajoutant un <xsl:vaue-of select="name()"/> à la correspondance, puis l'essayer en tant que "/" et "/ catalogue".

+0

oui - cela fonctionne, mais pourquoi l'exemple original ne fonctionne pas? – Goran

+0

Ahh. Mais pourquoi le paramètre n'est-il pas transmis à cd? – darasd

+0

Le catalogue est la racine ici, donc l'exemple original devrait fonctionner. Et c'est le cas avec libXSLT et Opera. – vartec

2

essayez de spécifier des modèles à appliquer:

<xsl:template match="/"> 
    <xsl:apply-templates select="catalog/cd"> 
    <xsl:with-param name="test" select="'has this parameter been passed?'"/> 
    </xsl:apply-templates> 
</xsl:template> 
+0

didn pas attraper ça - essayez cette solution. Il semble que quelque chose va de travers quand on ne spécifie pas le chemin des templates. – Goran

+0

oui, vous avez raison. Cependant, je crois qu'avoir // dans le select est une mauvaise forme. De plus, il semble que cette double barre oblique est cruciale pour passer des paramètres. Dans mon code réel, je passais déjà un nœud dans le select, cependant, le paramètre n'a été passé qu'après avoir préfixé le nœud avec //. POURQUOI? – darasd

+0

Ok - maintenant SO se comporte bizarrement - cette question n'a pas 4 réponses aussi vos modifications sont montrées et puis se perdent aléatoirement ... – Goran

0

Works pour moi avec libxslt 1.1.24 de http://xmlsoft.org/XSLT/ :

$ xsltproc xml1.xsl xml1.xml 
<?xml version="1.0"?> 


    parameter: 
    has this parameter been passed? 

    parameter: 
    has this parameter been passed? 
+0

intéressant. J'utilise MSXML 4.0. Cependant, il ne fonctionne pas lorsque je l'affiche dans Firefox. – darasd

+0

Oui, échoue avec Fx, fonctionne avec Opera 10. – vartec

0

Je vois le problème est qu'il n'y a pas de correspondance pour cd élément sous la racine. Sous root, vous avez élément catalogue pas élément cd, afin de modifier le modèle pour correspondre 'catalogue' =

2

vous pouvez toujours aller avec xsl: call-template .. par exemple:

... 
<xsl:call-template name="foo"> 
    <xsl:with-param name="bars" select="42"/> 
</xsl:call-template> 
... 

<xsl:template name="foo"> 
    <xsl:param name="bars"/> 
    <xsl:value-of select="$node"/> 
</xsl:template> 
Questions connexes