2010-10-24 13 views
5

Supongamos que tengo una plantilla foo que puede dar salida a algo dado un parámetro. Ahora quiero usar esa salida como un parámetro para mi otra plantilla, loop, así puedo repetir la salida un cierto número de veces. He intentado algo en el camino deXST - utilizando la salida de la plantilla de llamada como valor de retorno

<xsl:call-template name="loop"> 
     <xsl:with-param name="times" select="someParam"/> 
     <xsl:with-param name="output"> 
      <xsl:call-template name="foo"> 
       <xsl:with-param name="type" select="something"/> 
      </xsl:call-template> 
     </xsl:with-param> 
    </xsl:call-template> 

En otras palabras, output ahora debe contener la salida de la llamada a foo. Tanto loop como foo funcionan bien de forma independiente, pero parece que no puedo anidarlos de esta manera. ¿Cómo debo lograr esto? Gracias por adelantado.

+0

Buena pregunta, 1. Vea mi respuesta para un ejemplo de trabajo de su código provisto y para algunas recomendaciones. –

Respuesta

9

El problema está en el código que no nos ha mostrado. Esta es una forma correcta de las plantillas de la cadena/de tubería, aunque yo no lo recomendaría (ver al final de esta respuesta),

Esta transformación:

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

<xsl:template match="/"> 
    <xsl:call-template name="loop"> 
     <xsl:with-param name="times" select="3"/> 
     <xsl:with-param name="output"> 
      <xsl:call-template name="foo"> 
       <xsl:with-param name="pN" select="5"/> 
      </xsl:call-template> 
     </xsl:with-param> 
    </xsl:call-template> 
</xsl:template> 

<xsl:template name="loop"> 
    <xsl:param name="times" select="1"/> 
    <xsl:param name="output" select="2"/> 

    <xsl:choose> 
     <xsl:when test="not($times > 0)"> 
     <xsl:value-of select="$output"/> 
     </xsl:when> 
     <xsl:otherwise> 
     <xsl:call-template name="loop"> 
     <xsl:with-param name="times" select="$times -1"/> 
     <xsl:with-param name="output" select="2*$output"/> 
     </xsl:call-template> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

<xsl:template name="foo"> 
    <xsl:param name="pN" select="1"/> 

    <xsl:value-of select="2*$pN"/> 
</xsl:template> 
</xsl:stylesheet> 

cuando se aplica en cualquier XML (no utilizado), produce el, resultado correcto deseada:

80 

recomendación estilística:

Trate de evitar encadenar plantillas de esta forma ya que esto da como resultado un código ilegible y no legible.

Es mucho mejor obtener los resultados intermedios en las variables (correctamente nombradas). No solo es el código más legible y mantenible de esta manera, sino que cualquier resultado intermedio puede reutilizarse varias veces sin la necesidad de volver a evaluarlo.

aquí es la misma transformación, pero factorizar para satisfacer las exigencias estilísticas recomendados:

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

<xsl:template match="/"> 
    <xsl:variable name="vTwice"> 
    <xsl:call-template name="twice"> 
     <xsl:with-param name="pN" select="5"/> 
    </xsl:call-template> 
    </xsl:variable> 

    <xsl:call-template name="loop"> 
     <xsl:with-param name="pTtimes" select="3"/> 
     <xsl:with-param name="pN" select="$vTwice"/> 
    </xsl:call-template> 
</xsl:template> 

<xsl:template name="loop"> 
    <xsl:param name="pTtimes" select="1"/> 
    <xsl:param name="pN" select="2"/> 

    <xsl:choose> 
     <xsl:when test="not($pTtimes > 0)"> 
     <xsl:value-of select="$pN"/> 
     </xsl:when> 
     <xsl:otherwise> 
     <xsl:call-template name="loop"> 
     <xsl:with-param name="pTtimes" select="$pTtimes -1"/> 
     <xsl:with-param name="pN" select="2*$pN"/> 
     </xsl:call-template> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

<xsl:template name="twice"> 
    <xsl:param name="pN" select="1"/> 

    <xsl:value-of select="2*$pN"/> 
</xsl:template> 
</xsl:stylesheet> 
+0

+1 Respuesta correcta. –

Cuestiones relacionadas