私はXSLTが初めてなので、2つのタグについて少し混乱しています。
<xsl:apply-templates name="nodes">
そして
<xsl:call-template select="nodes">
それで、それらの違いをリストアップできますか?
<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の真の力です。任意の数の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
とpriority
、テンプレートはname
とmatch
の両方を持つことができるという事実。また、テンプレートがインポートされたかどうか(<xsl:import>
)にも影響します。これらは高度な用途であり、そこに着いたら対処することができます。
@Tomalakによる良い答えに追加するには:
ここにいくつかの言及されていない重要な違いがあります:
xsl:apply-templates
はxsl:call-templates
よりもはるかに豊かで深いです。さらにxsl:for-each
からでも、単にわからないからです選択のノードに適用されるコード-一般的な場合、このコードはノードリストの異なるノードで異なります。
適用されるコードは、xsl:apply template
sが書き込まれた後、元の作者を知らない人が書くことができます。
FXSLライブラリ のXSLTでの高次関数(HOF)の実装は、XSLTができなかった場合は不可能です<xsl:apply-templates>
命令があります。
Summary:テンプレートと<xsl:apply-templates>
命令は、XSLTがポリモーフィズムを実装および処理する方法です。
リファレンス:このスレッド全体を見る:http://www.biglist.com/lists/ lists.mulberrytech.com/xsl-list/archives/200411/msg00546.html
xsl:apply-templates
は通常、(必ずしもではないが)allの適用可能なテンプレートを使用して、現在のノードのすべてまたは子のサブセットを処理するために使用されます。これは、処理された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ノードのすべての子にすべてのテンプレートを適用します。
機能は確かに似ています(呼び出しセマンティクスを除き、call-template
にはname
属性と対応する名前テンプレートが必要です)。
ただし、パーサーは同じ方法で実行されません。
MSDN から:
<xsl:apply-templates>
とは異なり、<xsl:call-template>
は現在のノードまたは現在のノードリストを変更しません。