重构时抑制模板中执行的某些代码的最佳方法是什么?

时间:2013-12-05 00:56:36

标签: xslt xslt-1.0

我们有这样的模板:

<xsl:template name = "MyTemplate">
    <!-- do some stuff-->
    <xsl:apply-templates select = "Node"/>
</xsl:template>

我们用

来称呼它
<xsl:call-template name="MyTemplate"/>

现在我们要重构这个,这样每次调用模板时都不一定会应用内部应用模板。我们想要在调用外部模板时决定是否应该应用它。

但是,我们不希望(或者在这一点上不同意我)通过并重构外部模板的每个现有调用,而是我们应该只重构我们希望功能发生变化的现有用法。

我们有几种方法可以做到这一点:

首先,我们可以使用XSLT布尔值或字符串来确定它是否应该运行。

布尔:

<xsl:template name = "MyTemplate">
    <xsl:param name="UseNode" select = "true()"/>
    <!-- do some stuff-->

    <xsl:if test="$UseNode = true()">
        <xsl:apply-templates select = "Node"/>
    </xsl:if>
</xsl:template>

字符串:

<xsl:template name = "MyTemplate">
    <xsl:param name="UseNode" select = 'true'/>
    <!-- do some stuff-->

    <xsl:if test="$UseNode = 'true'">
        <xsl:apply-templates select = "Node"/>
    </xsl:if>
</xsl:template>

其次,我们可以使用参数将其设置为 suppress ,或使用参数使用

使用:

<xsl:template name = "MyTemplate">
    <xsl:param name="UseNode" select = "true()"/>
    <!-- do some stuff-->

    <xsl:if test="$UseNode = true()">
        <xsl:apply-templates select = "Node"/>
    </xsl:if>
</xsl:template>

使用节点:

<xsl:call-template name="MyTemplate"/> 

不要使用节点:

<xsl:call-template name="MyTemplates">
    <xsl:with-param name="UseNode" select = "false()"/>
</xsl:call-template>

禁止:

<xsl:template name = "MyTemplate">
    <xsl:param name="SuppressNode" select = "false()"/>
    <!-- do some stuff-->

    <xsl:if test="$SuppressNode = false()">
        <xsl:apply-templates select = "Node"/>
    </xsl:if>
</xsl:template>

使用节点:

<xsl:call-template name="MyTemplate"/> 

不要使用节点:

<xsl:call-template name="MyTemplates">
    <xsl:with-param name="SuppressNode" select = "true()"/>
</xsl:call-template>

重构此模板的最佳方法是什么?为什么?

2 个答案:

答案 0 :(得分:3)

您不需要

  <xsl:if test="$UseNode = true()">

简单地

  <xsl:if test="$UseNode">

如果UseNode是(或可以强制转换为)布尔值。

同样$SuppressNode = false()"not($SuppressNode)

但是我可能会使用更简单的方案并且有两个模板而不是运行时开关。

<xsl:template name = "MyTemplate1">
    <!-- do some stuff-->
</xsl:template>

<xsl:template name = "MyTemplate2">
    <xsl:call-template name="MyTemplate1"/>
    <xsl:apply-templates select = "Node"/>
</xsl:template>

然后,您可以致电MyTemplate1MyTemplate2。除非在您的实际情况中,您有多个参数和许多不同的值组合,在这种情况下,您需要许多命名模板而不是参数化模板,这不会那么方便。

答案 1 :(得分:1)

你已经很好地概述了选项;他们都会工作。除非在非常特殊的情况下,我希望它们在实践中都难以区分(David Carlisle是正确的,将编译时选择推入运行时有成本,但我希望大部分时间都不会感觉到成本,所以我我不会担心,除非我不得不这样做。

哪个最好?

对于那个从现在开始尝试修复错误或扩展样式表功能三个月后最终阅读此代码的可怜的傻瓜来说,这个问题最容易实现。在上下文中,你可能是最好的判断。

(但值得的是:在这些情况下我通常使用字符串'yes'和'no',因为这些是XSLT本身做布尔人的方式;其他人显然更喜欢真正的布尔,因为David Carlisle已经有了平均而言,我发现像SuppressNode这样的参数,名称中包含否定,8.32%的可能性让我迷惑并让我停下来纠正正确的极性,而不是具有正面含义的参数UseNode 1}}。所以如果是我,我可能会以UseNode参数默认为yes开始。但后来我读了David Carlisle的答案并更改为两个名为MyTemplate的模板和MyTemplate-SuppressNode,因为调用模板是调用者中的一行,带参数的调用模板是三行。)