【问题标题】:XSL apply-templates priorityXSL 应用模板优先级
【发布时间】:2013-10-11 11:13:55
【问题描述】:

我有问题,我需要你。

我有一个想法用下面的代码解决它:

<xsl:template match="root">
    <xsl:apply-templates/>
</xsl:template>

<xsl:template match="*[@foo]" priority="3">
    <p>This text must be systematically added for any rendered element having a foo attribute</p>
    <xsl:apply-templates select="."/>
</xsl:template>

<xsl:template match="bar1">
    <p>This is the normal rendering for the bar1 element</p>
</xsl:template>
<xsl:template match="bar1[@class='1']">
    <p>This is the normal rendering for the bar1 element with class 1</p>
</xsl:template>
<xsl:template match="bar1[@class='2']">
    <p>This is the normal rendering for the bar1 element with class 2</p>
</xsl:template>
...
<xsl:template match="barN">
    <p>This is the normal rendering for the barN element</p>
</xsl:template>

当我尝试将此 xsl 应用于以下 xml 时:

<root>
    <bar1 foo="1"></bar1>
    <bar1 foo="1" class="1"></bar1>
    <bar1 class="2"></bar1>
    <bar1></bar1>
    ...
    <barN foo="n"></barN>
    <barN></barN>
</root>

XSLT 引擎在 priority="3" 模板上无限循环,而不是(根据我的需要)先应用一次 priority="3" 模板,然后应用 bar1 .. barN 模板。

如何在不修改每个 bar1 .. barN 模板 (N~=150) 的情况下执行此操作以在每个具有 foo 属性的元素上添加系统文本?

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    &lt;xsl:apply-templates select="."/&gt; 总是会选择最具体的模板,这确实可能导致无限递归。如果您使用的是 XSLT 2.0,那么您可以使用

    <xsl:next-match/>
    

    而是选择当前正在执行的模板之后的下一个最高优先级模板。在 XSLT 1.0 中,唯一的选择是将通用模板移动到不同的 .xsl 文件中,让您的主要模板导入该文件,然后使用 &lt;xsl:apply-imports/&gt; 应用具有“较低导入优先级”的模板(即仅考虑imported 文件,而不是 importing 文件)。

    classes.xsl

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    
        <xsl:template match="bar1">
            <p>This is the normal rendering for the bar1 element</p>
        </xsl:template>
        <xsl:template match="bar1[@class='1']">
            <p>This is the normal rendering for the bar1 element with class 1</p>
        </xsl:template>
        <xsl:template match="bar1[@class='2']">
            <p>This is the normal rendering for the bar1 element with class 2</p>
        </xsl:template>
        ...
        <xsl:template match="barN">
            <p>This is the normal rendering for the barN element</p>
        </xsl:template>
    
    </xsl:stylesheet>
    

    ma​​in.xsl

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    
        <xsl:import href="classes.xsl" />
    
        <xsl:template match="*[@foo]" priority="3">
            <p>This text must be systematically added for any rendered element having a foo attribute</p>
            <xsl:apply-imports/>
        </xsl:template>
    </xsl:stylesheet>
    

    【讨论】:

    • 使用模板优先级和apply-imports的简洁解决方案。
    • 是的!谢谢,正是我需要的。我使用&lt;xsl:next-match/&gt; 解决方案,但我将&lt;xsl:apply-imports/&gt; 的解决方案保存在内存中,以防XSLT 1.0
    【解决方案2】:

    您可以使用模板模式。

    <xsl:template match="*[@foo]">
        <p>This text must be systematically added for any rendered element having a foo attribute</p>
        <xsl:apply-templates select="." mode="normal" />
    </xsl:template>
    
    <xsl:template match="bar1" mode="normal">
        <p>This is the normal rendering for the bar1 element</p>
    </xsl:template>
    
    <!-- ... -->
    
    <xsl:template match="barN" mode="normal">
        <p>This is the normal rendering for the barN element</p>
    </xsl:template>
    

    关键是,当&lt;xsl:template match="*[@foo]"&gt; 匹配某个东西并且你在其中调用一个简单的&lt;xsl:apply-templates select="." /&gt; 时,同一个模板当然会再次匹配。

    【讨论】:

    • 我已经考虑过使用它,但我已经将它们用于其他约束。不过谢谢。
    • 你应该在问题中这么说。
    • 抱歉,上下文非常特殊,我只是忘记列出所有约束
    猜你喜欢
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 2016-04-08
    • 1970-01-01
    • 1970-01-01
    • 2011-05-13
    • 2017-04-14
    • 2021-01-01
    相关资源
    最近更新 更多