XSLT:执行流程的调用模板vs模式

时间:2010-09-17 17:57:49

标签: xml xslt

哪种方法更适用于执行流程,调用模板或模式?

data.xml中

<Properties>
    <foo>me</foo>
    <bar>you</bar>
</Properties>

a.xsl

<xsl:include href="translations_nomodes.xml"
<xsl:template match="/">
    <xsl:call-template name="a_display"/>
</xsl:template>

b.xsl

<xsl:include href="translations_nomodes.xml"
<xsl:template match="/">
    <xsl:call-template name="b_display"/>
</xsl:template>

translations_nomodes.xsl

<xsl:template name="a_display">
    <!-- display option a -->
    ...
</xsl:template>

<xsl:template name="b_display">
    <!-- display option b -->
    ...
</xsl:template>

或者使用模式是更好的做法

c.xsl

<xsl:include href="translations_modes.xml"
<xsl:template match="/">
    <xsl:apply-templates select="/Properties" mode="c_display"/>
</xsl:template>

d.xsl

<xsl:include href="translations_modes.xml"
<xsl:template match="/">
    <xsl:apply-templates select="/Properties" mode="d_display"/>
</xsl:template>

translations_modes.xsl

<xsl:template match="Properties" mode="c_display">
    <!-- display option c -->
    ...
</xsl:template>

<xsl:template match="Properties" mode="d_display">
    <!-- display option d -->
    ...
</xsl:template>

由于“Properties”是我的文档中的根节点,而apply-templates使用文字作为模式值,因此使用模式不会给我任何额外的好处,而且稍微冗长一些。但是,如果执行流程依赖于文档本身中的元素/属性,并且模式不是文字而是表达式,那么我可以看到模式方法的必要性。

事实上,像我一样使用模式,使用文字值,似乎也是一个糟糕的选择,因为如果我的逻辑发生变化,我需要使用模式表达式来控制执行流程,我已经“使用”了模式属性。

我是否得出了正确的结论,或者我错过了一些重要的观点?

2 个答案:

答案 0 :(得分:3)

回答这个问题的时间已经很晚了。 apply-templates和call-template之间的一个重要区别是,在后一种情况下,被调用的模板继承了调用者的当前节点(有时称为上下文节点)。而使用apply-template,select =“expr”通过生成节点列表然后迭代它们来确定上下文模式。

使用您的示例,a.xsl和b.xsl都匹配“/”。当他们在translations_nomodes.xsl中调用模板a_display和b_display时,这些模板继承“/”作为上下文节点。

相反,c.xsl和d.xsl中的模板使用select =“/ Properties”应用模板。由于只有一个“/ Properties”,它是列表中唯一要迭代的节点,它成为XSLT处理器寻找最佳匹配的上下文节点。因此,translations_modes.xsl中的模板将“/ Properties”视为上下文节点。

那么更好的做法是哪种?取决于您是要继续使用当前上下文节点进行处理还是选择其他节点开始处理。

希望有所帮助。

答案 1 :(得分:0)

请记住:XSLT(与任何声明性语言一样)将具有众所周知架构的输入绑定到具有众所周知架构的输出。

没有“一般解决方案”这样的东西。

看一下你的例子,这就是事实:

  • 您的输入来源有Properties 根元素。
  • 您的流程逻辑不会停留在 XSLT,但在您的决定中:运行 一个或另一个转变。

那么,为什么你有一个带有单独逻辑的通用样式表,以及每个逻辑的两个“入口点”样式表?这没有意义。

最佳做法是拥有两个样式表。