2011-12-17 15 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

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

index2.xslを呼んでいるがにテンプレートを適用する方法はありますindex.xslに<xsl:call-template name="temp2" />の結果がありますか?

ありがとうございます。

答えて

8

index.xslで <xsl:call-template name="temp2" />の結果にテンプレートを適用する方法はありますか?

はい、これはマルチパス処理呼ばれます。唯一の唯一の特質は、一般的に悪名高いRTF(Result Tree Fragment)型の中間結果に実装依存のxxx:node-set()拡張関数を適用しなければならず、したがって通常のツリーに変換する必要があるということです。ここで

は、マルチパス処理の完全な例である(私は 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元素の含有量は、1パス目で倍増され、第2のパスで乗)に製造される:

<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

関連する問題