在XSLT中,我可以只运行一次模板吗

在XSLT中,我可以只运行一次模板吗,xslt,Xslt,我有一块XSLT,可以在整个转换过程中多次应用。但我希望它只在第一次应用时运行,它应该在以后的所有时间都被跳过。我该怎么做 举个例子,这就是我想做的事情: 在样式表中,我定义了一个全局变量: <xsl:variable name="run_once" select="0"/> 然后我有一个模板,它被多次调用: <xsl:template name="some_template"> <xsl:if test="$run_once != 1">

我有一块XSLT,可以在整个转换过程中多次应用。但我希望它只在第一次应用时运行,它应该在以后的所有时间都被跳过。我该怎么做

举个例子,这就是我想做的事情: 在样式表中,我定义了一个全局变量:

<xsl:variable name="run_once" select="0"/>

然后我有一个模板,它被多次调用:

<xsl:template name="some_template">
    <xsl:if test="$run_once != 1">
        <xsl:variable name="run_once" select="1"/>
        <xsl:text>THIS TEXT SHOULD APPEAR ONLY ONCE</xsl:text>
    </xsl:if>
</xsl:template>

此文本应仅显示一次
这当然行不通,因为变量不能更改,只能重载。因此,一旦some_模板退出,$run_once再次为0,并且每次调用模板时都应用文本。 是否有某种类型的ifdef功能或其他全局对象可以设置

如果您对我为什么要这样做感兴趣,下面将更详细地解释我的问题和我使用的解决方案:

  • 我的输入是原始XML中的数据,我的 输出是WordML格式的报告
  • 在输入中,我有一系列节点 (命名为节点)。有些,但不是 所有这些节点都需要 显示在输出中。节点 仅当XPATH 发性恋是正确的(发性恋明显是长而短的) 复杂的)
  • 节点还具有类型(存储在 子节点)。在输入中,所有 相同类型的节点将 总是被分组在一起。在 输出,所有相同的节点 类型应分组在 该类型的特定标题(有 每个标题只能有一个标题 类型)
这就是我最终使用的解决方案:

...
<xsl:apply-templates select="theNode[hairyLogic]"/>
...

<xsl:template match="theNode">
    <xsl:if test="count(preceding-sibling::theNode[type = current()/type and hairyLogic])=0">
        <xsl:choose>
            <xsl:when test="type = 'TYPE1a' or type = 'TYPE1b'">
                <xsl:call-template name="TYPE1Heading"/>
            </xsl:when>
            <xsl:when test="type = 'TYPE2'">
                <xsl:call-template name="TYPE2Heading"/>
            </xsl:when>
        </xsl:choose>
    </xsl:if>
    ...
</xsl:template>
。。。
...
...
我选择为标题使用命名模板,因为它们包含基本WordML,不依赖于输入XML中的任何数据


我不喜欢这个解决方案,因为hairyLogic是重复的,if语句很复杂,很难阅读。也许您有一个更好的解决方案,它不需要可变变量?

因为XSLT是一种纯粹的函数式语言,所以没有可以设置的全局变量


相反,您必须选择在什么情况下调用
some\u模板
template。如果只想调用一次,那么只需调用一次。

我建议使用匹配模板而不是命名模板,因为它更重要,那么XSLT的等价物是什么?Xslt-y?我想你会发现用这种处理方法你可以更容易地解决问题

如果您因为一些未知的需求而坚持使用命名模板,您可能会发现,如果您重构您的逻辑使其易于检测第一个实例,您将完全简化您的逻辑

你能解释一下为什么你不能检测到何时需要第一个实例吗?我们可能可以帮助您设计一个xpath表达式,让您可以随心所欲地使用它。例如

<xsl:template name="some_template">
    <xsl:variable name="EXPRESSION" select=".[somelogic='true']"/>
    <xsl:if test="$EXPRESSION">
        <xsl:text>THIS TEXT SHOULD APPEAR ONLY ONCE</xsl:text>
    </xsl:if>
</xsl:template>

此文本应仅显示一次

因为XSLT是确定性的——正如Greg所说,这是一种完全功能化的效果(除非你在做奇怪的扩展),你可以通过对输入应用逻辑来决定第一次何时合适。此外,您还可以访问模板中的上下文节点,以便知道从何处调用它。

“什么是pythonic?XSLT-y的XSLT等价物?”-它是“声明性”的。是的,我有一些没有详细说明的约束条件(如果您感兴趣,请添加到问题中)。我用你描述的方式解决了这个问题。我不喜欢它,因为“somelogic”很长,很混乱,现在重复了好几次。如果我可以像在其他函数式语言中一样,在解析XPATH代码时进行口述,那就不会太糟糕了。然后,我可以将“somelogic”的错误部分存储在变量中,并在需要时将其插入表达式中。