XSLT - 将模板应用于调用模板结果

时间:2011-12-17 21:23:17

标签: xslt

是否可以将模板应用于调用模板的结果?

例如,下面是xml和2 xslt。

INDEX.XML:

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <book>
    <title>Ethics</title>
  </book>
  <book>
    <title>Beyond Good and Evil</title>
  </book>
</root>

index2.xsl

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:template match="/" name="temp2">
    <foo>
    <xsl:for-each select="//book">
      <bar><xsl:value-of select="."/></bar>
    </xsl:for-each>
    </foo>
  </xsl:template>
</xsl:stylesheet>

和index.xsl正在调用index2.xsl

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
<xsl:include href="index2.xsl" />
<!-- apply a template to the <xsl:call-template name="temp2" /> result -->
</xsl:stylesheet>

有没有办法将模板应用于index.xsl中<xsl:call-template name="temp2" />的结果?

提前致谢。

1 个答案:

答案 0 :(得分:8)

  

有没有办法将模板应用于结果   index.xsl中的<xsl:call-template name="temp2" />

是的,这称为 多遍处理。唯一的特点是在XSLT 1.0中你必须将依赖于实现的xxx:node-set()扩展函数应用于任何中间结果,这通常是臭名昭着的RTF(结果树片段)类型,因此需要转换为一棵普通的树。

以下是多次传递处理的完整示例(我使用的是xsl:apply-templates而不是xsl:call-template,但您可以自由修改此示例以使用命名模板和{ {1}}代替):

xsl:call-template

将此转换应用于以下XML文档

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common" exclude-result-prefixes="ext">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/*">
  <xsl:variable name="vrtfPass1">
   <xsl:apply-templates select="num"/>
  </xsl:variable>

  <xsl:apply-templates mode="pass2"
    select="ext:node-set($vrtfPass1)/*"/>
 </xsl:template>

 <xsl:template match="num">
  <num><xsl:value-of select="2* ."/></num>
 </xsl:template>

 <xsl:template match="num" mode="pass2">
  <num><xsl:value-of select=". * ."/></num>
 </xsl:template>
</xsl:stylesheet>

想要的结果(任何<nums> <num>01</num> <num>02</num> <num>03</num> <num>04</num> <num>05</num> <num>06</num> <num>07</num> <num>08</num> <num>09</num> <num>10</num> </nums> 元素的内容在第一遍中加倍,然后在第二遍中加平)

num

<强> II。在XSLT 2.0中

取消了RTF“类型”,因此指定多遍处理要容易得多,这几乎与功能组合无法区分,如下面的等效转换所示:

<num>4</num>
<num>16</num>
<num>36</num>
<num>64</num>
<num>100</num>
<num>144</num>
<num>196</num>
<num>256</num>
<num>324</num>
<num>400</num>

将此转换应用于同一XML文档(上图)时,会生成相同的正确结果

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my" exclude-result-prefixes="my">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/*">
  <xsl:sequence select="my:squareAll(my:doubleAll(*))"/>
 </xsl:template>

 <xsl:function name="my:doubleAll" as="element()*">
  <xsl:param name="pElems" as="element()*"/>

  <xsl:for-each select="$pElems">
   <xsl:copy>
    <xsl:sequence select=". + ."/>
   </xsl:copy>
  </xsl:for-each>
 </xsl:function>

 <xsl:function name="my:squareAll" as="element()*">
  <xsl:param name="pElems" as="element()*"/>

  <xsl:for-each select="$pElems">
   <xsl:copy>
    <xsl:sequence select=". * ."/>
   </xsl:copy>
  </xsl:for-each>
 </xsl:function>
</xsl:stylesheet>