2009-01-26 9 views
12

¿Hay alguna manera de escribir una plantilla XSL 1.0 que coincida en todos los modos?¿Puede una plantilla XSL coincidir en los modos * TODOS *?

¿O tengo que escribir una plantilla separada para cada modo existente (incluidas las plantillas adicionales para los modos que se agreguen en el futuro)?

Aquí es lo que tengo:

<xsl:apply-templates mode="mode1" /> 
    ... 
<xsl:apply-templates mode="mode2" /> 
    ... 
<!-- Do not process text content of nodes no matter in what mode --> 
<!-- Is there a way to have only one template here? --> 
<xsl:template match="text()" mode="mode1" /> 
<xsl:template match="text()" mode="mode2" /> 
+0

@divo No recomendaré a nadie que use #all en XSLT 2.0 - es demasiado peligroso. Por ejemplo, solo un poco de plantilla más genérica (matching node()) interferirá con * cualquier otra * plantilla.Mucho mejor es diseñar las plantillas con más cuidado, de una manera más limpia, para que #all no sea necesario. –

+0

@divo No necesita plantillas vacías que coincidan con text() si usa en lugar de usar

+0

@Dimitre: Sí, por supuesto, tienes razón. Sin embargo, su solución implica la modificación de cada plantilla de aplicación en el código, lo que hace que el mantenimiento sea bastante difícil y me parece que es propenso a errores. –

Respuesta

7

El modo predefinido: #all (sólo disponible en XSLT 2.0, sin embargo).

edición: replicar el comportamiento de modo compartido con 1,0

<xsl:template match="/"> 
    <xsl:variable name="choice" select="'a'"/><!-- input seed here --> 
    <xsl:choose> 
     <xsl:when test="$choice='a'"> 
      <xsl:apply-templates mode="a"/> 
     </xsl:when> 
     <xsl:when test="$choice='b'"> 
      <xsl:apply-templates mode="b"/> 
     </xsl:when> 
    </xsl:choose> 
</xsl:template> 

<xsl:template match="*" mode="a"> 
    [A] 
    <xsl:apply-templates /> 
</xsl:template> 

<xsl:template match="*" mode="b"> 
    [B] 
    <xsl:apply-templates /> 
</xsl:template> 

<xsl:template match="text()"> 
    [ALL] 
</xsl:template> 
+0

¡Sería realmente bueno tenerlo! Gracias por la respuesta, pero parece que solo XSLT 2.0 y olvidé mencionar que estoy restringido al usar XSLT 1.0 :-(Parece que tendré que escribir una plantilla por separado de todos modos ... –

+0

Ah, en ese caso, al menos deberías ser capaz de envolver el código común en una plantilla nombrada o no modal a la que puede llamar desde las dos horquillas de modo. – annakata

+0

@annakata No veo cómo su código XSLT 1.0 actuaría como si hubiera una plantilla seleccionada en todos los modos ¿Podría usted, por favor, editar su respuesta y explicar? –

1

Si usted quiere tener el partido plantilla en todos los modos a continuación, ¿por qué estás usando el modo? Si no usa el modo, la plantilla se usará todo el tiempo. El motivo del modo es realizar de manera condicional cosas diferentes con el mismo tipo de datos. Parece que quieres ser no modal.

+1

, si ya estaba dentro de una horquilla de modo (para algún propósito útil) no se hará referencia a las plantillas de modo predeterminadas – annakata

+0

No, necesito varios modos para procesar nodos varios veces haciendo cosas diferentes. Sin embargo, no quiero procesar el contenido de ciertos nodos en ningún modo. La única solución parece escribir una plantilla separada para cada modo. –

+0

(continuación) Y una plantilla no modal solo coincidirá con una "llamada" de plantillas de aplicación no modal. –

2

¿Hay una manera de escribir una plantilla XSL 1.0 que es coincidente en todos los modos

Sí, con el fin de hacer esto, uno debe seguir estas dos reglas:

  1. Escriba su plantilla sin un atributo de modo.

  2. Dentro de las plantillas moded tienen una instrucción <xsl:apply-templates>sin un atributo de modo de que resultará en la plantilla en 1. arriba ser seleccionado para el procesamiento de

Esto se deduce directamente de la XSLT 1.0 spec, which says:

Si un elemento xsl:apply-templates tiene un mode atributo, luego aplica solo a las reglas de plantilla de xsl:template elementos que tienen un atributo mode con el mismo valor; si un elemento xsl:apply-templates qué no tienen un atributo mode, a continuación, se aplica sólo a aquellos reglas plantilla de xsl:template elementos que no tienen un atributo mode.

Para resumir: Un conjunto de plantillas de cada uno en un modo diferente todavía puede emitir <xsl:apply-templates> de tal manera (descrito anteriormente), de modo que se seleccionará el mismo específico, sola plantilla para el procesamiento en cada caso.

+0

Esto podría funcionar en el ejemplo simple presentado aquí. Sin embargo, esto podría tener un efecto secundario cuando hay más de una plantilla no modal. El comportamiento exacet del modo #all de XSLT 2.0 no está disponible en XSLT 1.0 y apenas se puede simular. –

+0

@divo No recomendaré a nadie que use #all en XSLT 2.0, es demasiado peligroso. Por ejemplo, solo un poco de plantilla más genérica (matching node()) interferirá con * cualquier otra * plantilla. Mucho mejor es diseñar las plantillas con más cuidado, de una manera más limpia, para que #all no sea necesario. –

+0

Sí, debe usarse con cuidado, pero depende en gran medida de la situación. En mi caso, el contenido de los elementos de licencia debe * nunca * aparecer en el resultado, por lo tanto, la (s) plantilla (s) vacía (s) coincide (n) con el texto(). Sin embargo, no veo el problema con una plantilla más genérica, ya que "más específico" tiene mayor prioridad. –

Cuestiones relacionadas