2011-12-17 82 views
4

是否可以將模板應用於呼叫模板的結果?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" />的結果?

在此先感謝。

回答

8

有什麼辦法可以在index.xsl中將模板應用到 <xsl:call-template name="temp2" />的結果中嗎?

是的,這被稱爲多遍處理。唯一的特點是,在XSLT 1.0中,必須將實現依賴的xxx:node-set()擴展函數應用於任何中間結果,這通常將是臭名昭着的RTF(結果樹片段)類型,因此需要轉換爲常規樹。

這裏是多通道處理一個完整的示例(我使用xsl:apply-templates,而不是xsl:call-template,但你可以自由地修改此示例以使用命名模板和xsl:call-template代替):

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

當此轉換應用於以下XML文檔

<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元素的含量在第一遍被加倍,那麼在第二遍中的平方)產生

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

II。在XSLT 2.0

的RTF「類型」被廢除,因此它更容易地指定多遍處理,其成爲從功能組合物幾乎沒有區別,如下面的等效變換顯示:

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

當對相同的XML文檔(上面)被應用於這種轉變中,相同的正確的結果產生

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

Ve的ry清晰詳細的解釋,非常感謝! – Eric 2011-12-18 08:21:41