2009-01-26 57 views
12

有没有办法编写一个在所有模式下匹配的XSL 1.0模板?XSL模板可以匹配* ALL *模式吗?

或者我必须为每个现有模式(包括未来添加模式的其他模板)编写一个单独的模板吗?

以下是我有:

<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我不会推荐任何人在XSLT 2.0中使用#all - 这太危险了。例如,一个更通用的模板(匹配节点())会干扰*任何其他*模板。更好的办法是更仔细地设计一个模板,以更清晰的方式,这样就不需要#all。 – 2009-01-26 20:22:28

+0

@divo如果使用而不是使用 2009-01-26 22:44:34

+0

@Dimitre:是的,当然你是对的。但是,您的解决方案意味着修改代码中的每个应用程序模板,这使得维护非常困难,并且似乎对我来说很容易出错。 – 2009-01-27 15:51:10

回答

7

预定义模式:#all(仅在XSLT 2.0然而可用)。

编辑: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

这真的很棒!谢谢你的答案,但它似乎只有XSLT 2.0,我忘了提及我被限制使用XSLT 1.0 :-(看来我将不得不编写一个单独的模板... – 2009-01-26 12:29:42

1

如果你想在所有的模式,然后你为什么使用模式的模板匹配中的共享模式的行为吗?如果你不使用模式,模板将一直使用。模式的原因是有条件地用相同的数据类型做不同的事情。似乎你想要无模式。

2

有没有写这是在所有 模式

是相匹配的XSL 1.0 模板的方式,才能做到这一点应该遵循以下两条规则

  1. 编写模板没有模式属性

  2. 内moded模板具有<xsl:apply-templates>指令未经模式属性,这将导致在模板上面1被选择用于处理

这直接从XSLT 1.0属,which says如下

如果一个xsl:apply-templates元素有 a mode属性,则它仅适用于 到那些具有相同值的mode 属性的元素 xsl:template;如果 xsl:apply-templates元素不 有mode属性,那么它适用 只从 xsl:template元素的模板规则没有 一个mode属性。

总结:一组中的每个模板在不同的模式以这样的方式(上述)仍然可以发出<xsl:apply-templates>,使得相同的特异性的,单模板将在每种情况下被选择用于处理。