2016-08-25 128 views
0

我在XSL中有2个模板,我想在单个XSL文件中执行。 原始的XMLXSLT 1.0在另一个模板的结果上应用模板

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

这需要嵌套,然后重命名的元素名称。 但我无法弄清楚如何在1个单独的xslt中完成这2个模板。由于模板始终从原始的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个模板。

+0

为什么你不让我们更容易,并发布你有两个模板。特别是因为不清楚可以有多少步骤。 –

+0

@ michael.hor257k添加了它们,底部有两个我想合并的模板。目前我正在尝试使用xsl,如果在第一个模板的循环中。 –

回答

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"/> 
+0

“*一般来说,您应用的方式 - 将模板应用于之前模板的结果是将结果捕获到一个变量*”只有当两个模板匹配相同的节点时才有必要 - 在这里完全没有这种情况。 –

+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这项任务。应用模板到以前的模板的结果

+0

我对XSL非常新颖,从昨天开始我几乎了解到现在所知道的一切。我已经看过Muenchian分组方法,但似乎只能对值进行排序,而不是对元素名称本身进行排序?或者我理解错了,是否必须再看一遍? –

+0

@Pieter_mov你的理解是错误的。将键定义为''并继续。 –