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

标签 xslt

我有一个 XSLT block ,可以在整个转换中多次应用。但我希望它只在第一次应用时实际运行,它应该被跳过所有后续时间。我该怎么做呢?

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

<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_template 退出 $run_once 再次为 0,并且每次调用模板时都会应用文本。
我可以设置某种类型的 ifdef 功能或其他全局对象吗?

如果您对我为什么要这样做感兴趣,下面是对我的问题和我使用的解决方案的更详细说明:
  • 我的输入是原始 XML 中的数据,我的
    输出是 WordML 格式的报告。
  • 在输入中我有一系列节点
    (命名为 该节点 )。有些,但不是
    所有这些节点都需要
    显示在输出中。节点
    仅当 XPATH 时才应显示
    毛逻辑是真的(hairyLogic 显然很长并且
    复杂的)。
  • theNode 也有一个 类型 (存储在
    一个子节点)。在输入中,所有
    相同类型的节点将
    总是被组合在一起。在里面
    输出,所有相同的节点
    类型应归入一个
    该类型的特定标题(有
    每个应该只有一个标题
    类型)。

  • 这是我最终使用的解决方案:
    ...
    <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>
    

    我选择对标题使用命名模板,因为它们包含不依赖于输入 XML 中的任何数据的基本 WordML。

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

    最佳答案

    我建议使用匹配模板而不是命名模板,因为它更多,好吧,XSLT 等价于 pythonic ? 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 所说的那样,完全可以发挥作用——(除非你正在做奇怪的扩展工作)你可以通过对输入应用逻辑来决定第一次何时合适。此外,您可以访问模板中的上下文节点,以便知道从哪里调用它。

    关于xslt - 在 XSLT 中,我可以只运行一次模板吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1344120/

    相关文章:

    使用 XSLT 进行 XML 到 XML 转换 - 循环子节点

    xml - 使用 XSLT 创建站点是否有意义

    xml - XSL 检查以查看是否有任何子节点具有属性

    java - 如何使用 xslt 删除 xml 文件中的重复项?

    通过涉及特殊字符的 XSL 转换输出 HTML

    xslt - 循环 XSLT

    java - Ant :[xslt] java.lang.ClassNotFoundException:org.apache.tools.ant.taskdefs.optional.TraXLiaison

    html - XSLT 如何检查 XML 节点是否存在?

    xml - 我可以将多个 xsl 文件导入到另一个 xsl 文件吗?

    java - 从 XPath 表达式填充 XML 模板文件?