2010-12-16 8 views
14

xsl:for-eachxsl:templateの両方を使用して、xslスタイルシートのxmlからノードを取得します。しかし、彼らの根本的な違いは何ですか?私を案内してください。前もって感謝します。xslのfor-eachとtemplatesの違いは?

答えて

7

私はこれがちょうどxsl:for-eachまたはxsl:template match="..."を比較するよりも、理解push vs. pullスタイルの処理をどうするか、いくつかを持っていると思います。 xsl:if,xsl:choose、およびfor-loopsを多く使用している別の分野のプログラマーは、より洗練されたXSLTishの方法で問題が解決されていることがよくあります。

しかし、問題に:私の意見で、あなたがxsl:for-eachを使用しての代わりに、あなたは再考する必要があるxsl:apply-templatesでデータを処理して検討している場合。 XSLTではforループが適している場合がありますが、一致するテンプレートで同じことが行われるときはいつでも、テンプレートを使用する方法があります。私の経験上、普通xsl:for-eachのほうをxsl:apply-templatesで行うことができます。

私は、forループの上に一致するテンプレートを使用してのそれを見るようにいくつかの利点は次のとおりです。

  • スタイルシートを維持し、特に場合は、ソースデータの変更を拡張するのが容易です。
  • @chiborgには、テンプレートが特定のテンプレートに組み込まれていないため、再利用できると記載されています。 XSLT 2.0のxsl:next-matchと一緒に、強力な方法でテンプレートを連鎖させることができます。
  • 既にすべてのXSLTプロセッサに組み込まれている動作を模倣する必要はありません。 xsl:apply-templatesを使用し、プロセッサーがあなたのために働くようにしてください。
  • また、プッシュスタイルのスタイルシートを理解してデバッグする方が簡単です。スタイルシート情報を分割して1つまたは少数のものを作成し、特定の一致パターンを書くと、どのテンプレートが何をしているのかを簡単に把握し、問題の原因を突き止めることができます。
+0

各テンプレート内で何が起きているのかを簡単に知ることができますが、どのテンプレートがどのような順番で(呼び出されるのか)を知ることは難しいです。 – LarsH

+0

@LarsH:Oxygensを使って素晴らしいデバッグをするのは...;) –

+0

あなたはそうです、私は:-)それは時には命を救う人です。しかし、デバッグは、XML入力データを手元に持っていれば役立ちます...そして、その特定のデータインスタンスに対してのみ役立ちます。一方、理解してスタイルシートを読むことができるのであれば、特定の入力にかかわらず、スタイルシートを理解して読むことができない場合と比べて、何が起きることができるかどうかについて、さらに多くの結論を導き出すことができます。 – LarsH

1

for-eachは、テンプレートの1か所でのみ使用できます。テンプレートは別のapply-templatesコールで再利用できます。私は主にfor-eachの代わりにテンプレートを使用しています。

3

それは本当に問題ではありませんが、あなたは私が見つけたルールの次の親指それについて考えたいことがあります。、コードはコンテキスト 位置(位置())に依存している場合

  • <xsl:for-each>に入れてください。
  • コードがコンテキスト ノード(。または任意のロケーションパス)に依存する場合は、 を一致するテンプレートに配置します。
  • それ以外の場合は、名前付きテンプレートを使用します。

参考とで続きを読む: http://www.jenitennison.com/blog/node/9

1

これらは、異なるXSLT命令を完了するためのものです。

プルスタイル対プッシュよりも、これはより多くの再帰対反復のようなものです。

xsl:for-eachは、ステートレスな宣言的パラダイムにおけるすべての利点と反復の制約を備えた反復命令です。良いプロセッサは呼び出しスタックをポーリングするべきではありません。

xsl:apply-templatesは、一般的な再帰命令です。一般的にはxsl:call-templateよりも強力です。パターンマッチングメカニズムに選択したノードを「スロー」すると、本当に「動的関数呼び出し」となります。

5

両方「はそれぞれ-用」と「テンプレート」 はXSLのXMLからノードを検索するために使用されます。しかしその差 はここで基本的に

であることは、最も重要な違いの一部です:

  1. xsl:apply-templatesは、単に我々ためにも 、xsl:for-eachよりもはるかに豊かで深いです のノードでどのコードが適用されるのかわからない - 一般的なケースでは、このコードは の異なるノードになりますode-list。

  2. xsl:apply template sはを書かれ、元の作者を知らない 人々によって後 が道を書き込むことができます適用されるコード。 XSLTは<xsl:apply-templates>命令を持っていなかった場合はXSLTで高次関数(HOF)の

FXSL libraryの実装は不可能であろう。

要約:テンプレートと<xsl:apply-templates>命令は、XSLTが多態性を実装し、扱う方法です。

リファレンス:この全体のスレッドを参照してください:http://www.stylusstudio.com/xsllist/200411/post60540.html

+0

"この全体の糸" Dimitreは、このSOのページにはまだ何も書いていません。 – Roland

+0

@Roland、 "このスレッド全体"は、明るい人達の答えをまとめた参考資料として引用されています。この答えには、何か違うものがあると言う声明はありません。 –

10

私は一般的に他の回答に同意するが、私は私の経験では、xsl:for-eachと書かれたスタイルシートを読み、多くやすくなることができると言うだろう、理解して、維持してください。xsl:apply-templates ...特に暗黙の選択(またはselect="node()"のような非常に一般的な選択)を伴うxsl:apply-templatesが特にあります。

なぜですか?なぜなら、それぞれが何をするのかを見るのはとても簡単だからです。 apply-templatesでは、本質的に、(a)可能なすべてのXML入力について知っている必要があります(スキーマを持っている場合は簡単ですが、それでもスキーマをダイジェストしなければならず、多くの場合、スキーマを持たない特にパイプラインの1つのステージで送信される一時的な中間XMLデータの場合、スキーマを持っていても開発フレームワーク(ESBやCMSなど)がパイプラインのあらゆるポイントでXMLを検証する方法を提供しない場合があります。したがって、あなたの無効なデータクリープがすぐには通知されない場合)、どのノードの種類が選択されるのかを予測できます(コンテキストノードの子など)。 (b)スタイルシート内のすべてのテンプレートを調べて、どのテンプレートが最も優先度の高いノードに一致するかを確認します(ドキュメント順で最後に表示されます)。処理の順番は、ファイル全体、または異なるファイル(インポートまたはインクルード)をスキップすることもできます。これは、何が起こっているのかを「見る」ことを非常に困難にする可能性があります。

for-eachを使用すると、どのコードがインスタンス化されるか正確に知ることができます。for-each内のコード。そしてfor-eachは明示的なselect式を必要とするので、どのノードがマッチできるかを推測するために、より狭いフィールドを持つ可能性が高くなります。

私はapply-templatesがfor-eachよりはるかに強力で柔軟性があることを否定していません。これはまさにポイントです。より強力で柔軟性の高い構造で、制約や理解、デバッグ(およびセキュリティホールの防止)を難しくしています。 Rule of Least Power:「強力な言語(この場合は構造)が情報の再利用を禁止しています。」 (Also discussed here

apply-templatesを使用すると、各テンプレートはモジュール化され、再利用可能になりますが、スタイルシートはより複雑になり、テンプレート間の相互作用は少なくなります。 予測可能です。 for-eachを使用すると、処理の流れが予測しやすくなります。

<xsl:apply-templates />(または<xsl:for-each select="node()"/>)では、入力XMLの構造が変更されると、開発者のレビューなしにスタイルシートの動作が変更されます。これが良いか悪いかは、あなたがスタイルシートにどれくらい前から考えているか、そしてXMLスキーマ開発者とスタイルシート開発者(同じ人かもしれないし、別の組織に所属しているかもしれない人)

私にとっては、それは判断の呼び出しです。 HTMLのような文書指向のXMLを持っていて、多くの要素型が実際に多くの異なる型の子を持つことができ、任意の深さの階層構造を持ち、与えられた要素型の処理がその文脈にあまり依存しないapply-templatesは絶対不可欠です。一方、データ構造型のXMLで、予測可能な構造を持ち、同じ要素型を異なるコンテキストで使用することはしばしばありませんが、for-eachは読みやすく、デバッグするのがはるかに簡単です(したがって、正確かつ迅速に書き込むことができます)。

+1

+1これは受け入れられた回答よりもバランスの取れた評価だと思う。 – PandaWood

+0

@PandaWood、ありがとう。 – LarsH

1

1つの使用for-each私は言及していません:それを使用してコンテキストノードを別のドキュメントに切り替えることができます。私はそれを使ってデータXMLをHTML入力フォームに変換しました。データフィールドに一致したテンプレートには、変換するデータフィールドを記述したXSDのxs:elementという1つのノードを選択したfor-eachが含まれていました。

XSDの説明を使用すると、1つのデータフィールドをラジオボタングループ、ドロップダウンボックス、またはプレーンでシンプルなテキスト入力に変換できます。 for-eachなし私は同時に2つの文書を歩くことができませんでした。

一般に、私はマッチングテンプレートを好む。私は、それがすぐに、このノードのそれぞれのために、次に、次のもの、それからのもの、などのように、一度に適用される単一の変換の概念に対応することを見出します。

+0

+1。コンテキストノードを設定することは 'for-each'の重要な使用 - 良い点です。そして、しばしば、これはコンテキストノードを設定するための最も簡潔で明確な方法です。しかし、あなたは同じことをするために 'apply-templates'を使うこともできます。言い換えれば、「for-each」を使わずに、同時に2つのドキュメントを同時に歩くことができないのは当然だとは思いません。 'apply-templates'はモードを使い、パラメータを渡すことができます。 – LarsH