1

我有问题,我需要你。

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

<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 属性的元素上添加系统文本?

4

2 回答 2

4

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

<xsl:next-match/>

相反,它会在当前执行的模板之后选择下一个最高优先级的模板。在 XSLT 1.0 中,唯一的选择是将通用模板移动到不同的.xsl文件中,将您的主要模板导入该文件,然后用于<xsl:apply-imports/>应用​​具有“较低导入优先级”的模板(即只考虑 import ed文件中的模板,而不是导入一个)。

类.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>

主文件

<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>
于 2013-10-11T11:25:50.003 回答
0

您可以使用模板模式。

<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>

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

于 2013-10-11T11:26:33.490 回答