回答:
<xsl:call-template>
これは、従来のプログラミング言語で関数を呼び出すこととほぼ同じです。
文字列を出力するこの単純な関数のように、XSLTで関数を定義できます。
<xsl:template name="dosomething">
<xsl:text>A function that does something</xsl:text>
</xsl:template>
この関数はを介して呼び出すことができます<xsl:call-template name="dosomething">
。
<xsl:apply-templates>
XSLTの真の力は少し異なり、XSLTの真の力です。これは、任意の数のXMLノード(select
属性で定義したものは何でも)を取り、それらを反復します(これは重要です:apply-templatesはループのように機能します!)、一致するテンプレートを見つけます彼らのために:
<!-- sample XML snippet -->
<xml>
<foo /><bar /><baz />
</xml>
<!-- sample XSLT snippet -->
<xsl:template match="xml">
<xsl:apply-templates select="*" /> <!-- three nodes selected here -->
</xsl:template>
<xsl:template match="foo"> <!-- will be called once -->
<xsl:text>foo element encountered</xsl:text>
</xsl:template>
<xsl:template match="*"> <!-- will be called twice -->
<xsl:text>other element countered</xsl:text>
</xsl:template>
このようにして、XSLTプロセッサに少しの制御を放棄します。プログラムのフローがどこに行くかを決めるのではなく、プロセッサは、現在処理しているノードに最も適切な一致を見つけることによって行います。
複数のテンプレートがノードに一致できる場合は、より具体的な一致表現を持つテンプレートが優先されます。同じ特異性を持つ一致するテンプレートが複数存在する場合は、最後に宣言されたテンプレートが優先されます。
テンプレートの開発に集中でき、「配管」を実行するために必要な時間を短縮できます。プログラムは、より強力でモジュール化され、深くネストされず、高速になります(XSLTプロセッサーはテンプレートマッチング用に最適化されているため)。
XSLTで理解する概念は、「現在のノード」の概念です。<xsl:apply-templates>
各反復での現在のノードに移動し、一方で<xsl:call-template>
現在のノードは変更されません。つまり.
、呼び出されたテンプレート内のは、呼び出しテンプレート内のと同じノードを指します.
。これは、apply-templatesには当てはまりません。
これが基本的な違いです。テンプレートの動作に影響を与えるテンプレートには、他にもいくつかの側面があります。それらのmode
andとpriority
、テンプレートはa name
とaの両方を持つことができるという事実ですmatch
。また、テンプレートがインポートされている(<xsl:import>
)かどうかにも影響します。これらは高度な使用法であり、そこに着くと対処できます。
<xsl:apply-templates>
は、ループのように動作します。XSLTプロセッサ側の実装の違いは、XSLTプログラマとしての私には影響しません。結果は、並列化された実装と反復的な実装の両方でまったく同じです。しかし、命令的な背景を持つXSLT初心者にとっては<xsl:apply-templates>
、たとえ技術的にはそうでなくても、一種のfor-eachループとして想像することは役立ちます。
@Tomalakによる良い答えに追加するには:
ここにいくつかの言及されていない重要な違いがあります:
xsl:apply-templates
はxsl:call-templates
xsl:for-each
選択範囲のノードに適用されるコードがわからないため、から よりもさらに深く、より一般的です-一般に、このコードはノードリストのノードごとに異なります。
適用されるコードは、xsl:apply template
sが作成された後で、元の作成者を知らない人が作成できます。
XSLTに<xsl:apply-templates>
命令がない場合、FXSLライブラリのXSLTでの高次関数(HOF)の実装は不可能です。
要約:テンプレートと<xsl:apply-templates>
命令は、XSLTがどのようにポリモーフィズムを実装して処理するかです。
参照:このスレッド全体を参照してください:http : //www.biglist.com/lists/lists.mulberrytech.com/xsl-list/archives/200411/msg00546.html
xsl:apply-templates
通常(必須ではありません)は、現在のノードの子のすべてまたはサブセットを、適用可能なすべてのテンプレートで処理するために使用されます。これは、処理されたXMLの(可能な)再帰性と一致するXSLTアプリケーションの再帰性をサポートします。
xsl:call-template
一方、通常の関数呼び出しにはるかに似ています。通常、1つ以上のパラメーターを使用して、1つの(名前付き)テンプレートを実行します。
それでxsl:apply-templates
、興味深いノードの処理をインターセプトし、(通常)出力ストリームに何かを注入したい場合に使用します。典型的な(単純化された)例は
<xsl:template match="foo">
<bar>
<xsl:apply-templates/>
</bar>
</xsl:template>
一方、xsl:call-template
私は通常、いくつかのサブノードのテキストを一緒に追加したり、選択したノードセットをテキストまたは他のノードセットに変換したりするなどの問題を解決します。
特定の質問テキストへの追加の注釈として:
<xsl:call-template name="nodes"/>
これは、「ノード」という名前のテンプレートを呼び出します。
<xsl:template name="nodes">...</xsl:template>
これは以下とは異なるセマンティックです。
<xsl:apply-templates select="nodes"/>
...名前が「nodes」である現在のXMLノードのすべての子にすべてのテンプレートを適用します。
<xsl:apply-templates>
ループとして実装する必要のある公式のW3C仕様には何も示されていません。逆に、ノードリストの異なるノードの異なるアプリケーションは互いに完全に独立しているため、並列に実装できます。