XSLT 1.0在另一个模板的结果上应用模板

时间:2016-08-25 10:39:15

标签: xml xslt-1.0

我在XSL中有两个模板,我想在一个XSL文件中执行。 原始xml

<root>
    <step1.alfa/>
    <step1.bravo/>
    <step1.charlie/>
    <step1.delta/>
    <step2.alfa/>
    <step2.bravo/>
    <step2.charlie/>
    <step2.delta/>

这需要嵌套,然后重命名元素名称。 但我无法弄清楚如何在1个单独的xslt中完成这两个模板。因为模板总是从原始的xml开始 第一个输出

<root>
<step>
    <step1.alfa/>
    <step1.bravo/>
    <step1.charlie/>
    <step1.delta/>
</step>
<step>
    <step2.alfa/>
    <step2.bravo/>
    <step2.charlie/>
    <step2.delta/>
</step>

第二次输出

<root>
<step>
    <alfa/>
    <bravo/>
    <charlie/>
    <delta/>
</step>
<step>
    <alfa/>
    <bravo/>
    <charlie/>
    <delta/>
</step>

第一个模板是嵌套步骤,第二个是重命名它们。我只展示一个,但我有一个模板,用于每个需要重命名的元素。

<xsl:template match="Values" name="recursive-steps">
    <xsl:param name="var" select="2"/>
    <xsl:choose>
        <xsl:when test="$var > 0">
            <STEP>

                <xsl:for-each select="node()[starts-with(name(), concat('step', $var))]">
                    <xsl:copy-of select="."/>
                </xsl:for-each>
            </STEP>
            <xsl:call-template name="recursive-steps">
                <xsl:with-param name="var" select="$var - 1"/>
            </xsl:call-template>

        </xsl:when>
        <xsl:otherwise/>
    </xsl:choose>
</xsl:template>

<xsl:template match="*[substring(name(), string-length(name())-3) = 'alfa']">
    <ALFA>
        <xsl:apply-templates select="@*|node()" />
    </ALFA>
</xsl:template>

在这里添加了我想要合并的2个模板。

2 个答案:

答案 0 :(得分:0)

好吧,如果你想在第一个模板之后应用第二个模板,你应该改变这个部分:

<xsl:for-each select="node()[starts-with(name(), concat('step', $var))]">
   <xsl:copy-of select="."/>
</xsl:for-each>

为:

<xsl:apply-templates select="node()[starts-with(name(), concat('step', $var))]"/>

或者更确切地说:

<xsl:apply-templates select="*[starts-with(name(), concat('step', $var, '.'))]"/>

然而,你的第二个模板没有多大意义。我相信它应该是这样的:

<xsl:template match="*">
    <xsl:element name="{substring-after(name(), '.')}"/>
</xsl:template>

坦率地说,你的第一个模板也有点尴尬 - 我建议你调查Muenchian grouping来完成这项任务。

答案 1 :(得分:0)

通常,将模板应用于上一个模板的结果的方法是将结果捕获到变量中:

<xsl:variable name="temp">
  <xsl:apply-templates select="x" mode="phase-1"/>
</xsl:variable>

<xsl:apply-templates select="$temp" mode="phase-2"/>

但是因为变量是结果树片段,所以在XSLT 1.0中你必须使用exslt:node-set()扩展来解决对RTF的限制:

<xsl:apply-templates select="exslt:node-set($temp)" mode="phase-2"/>