XSLT リスト ビュー レンダリング システムの概要

最終更新日: 2011年2月2日

適用対象: SharePoint Foundation 2010

このトピックでは、Microsoft SharePoint Foundation でのリスト ビューのレンダリングの概要について説明します。このトピックを読み進めるには、スタイル シート、テンプレート、パラメーター、ノード ツリー、コンテキスト ノードなど、少なくとも XSLT の基礎概念を理解しておく必要があります。

XSLT スタイルシートによるレンダリング

SharePoint Foundation に含まれる XSLT スタイル シートは、%ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\LAYOUTS\XSL の .xsl ファイル内にあります。この中で最も重要なのは、vwsytles.xsl と fldtypes.xsl の 2 つのファイルです。最初のファイルには、リストを行レベルまでレンダリングするときに使用するスタイル シートが、2 つ目のファイルには、リスト ビューの特定のフィールド、つまりセルをレンダリングするときに使用するスタイル シートが用意されています。また、main.xsl には、多数のグローバル XSLT 変数が定義されています。

XSLT スタイル シートは、ある XML 言語でソース ノード ツリーを解析し、別の XML 言語で結果ノード ツリーを生成します。最もシンプルなケースでは、ソース ツリーが結果ツリーに変換されます。これは、XSLT テンプレートによって実行されます。この XSLT テンプレートはある種の規則で、この規則に基づいて、ソース マークアップの特定のフラグメントがどのように結果のフラグメントに変換されるかが決まります。ただし、必ずしもソース ノード ツリーのすべて (かつ唯一) の情報が、変換によって結果の言語で単純に再表現されるわけではありません。変換を実行することで、ソース ツリーから情報を除外し、ソースにはない情報を結果に挿入できます。特に、XSLT テンプレートを使用すると、複数の入力ノード ツリーの情報を組み合わせることができます。追加の各入力ノード ツリーは、ソース ノード ツリーと合わせて、パラメーターとしてテンプレートに渡されます。SharePoint Foundation のリスト ビュー レンダリング XSLT テンプレートには、以下の 2 つの入力ノード ツリーがあります。

  • ソース ノード ツリー: リストの現在のビューを定義する ビュー スキーマ マークアップです。XSLT プロセッサが結果ツリーを作成するときに解析およびスキャンするのはこのツリーです。したがって、XSLT 変換中はいつでも、このマークアップのノードが XSLT プロセッサの "コンテキスト ノード" です。

  • thisNode パラメーター ツリー: 呼び出しテンプレートによって、各 XSLT フィールド レンダリング テンプレートに渡されます。このマークアップには、リストの実際のデータが含まれます。フィールドがレンダリングされるときに、実際のフィールド値がこのパラメーターから取得されます。thisNode パラメーター内のマークアップの詳細なリファレンスについては、「dsQueryResponse XML」を参照してください。

これらのノード ツリーの例については、XSLT 変換での入力と結果ノード ツリーの例」を参照してください。

XSLT テンプレートの階層

SharePoint Foundation の XSLT テンプレートの階層は非常に複雑です。リスト ビューのレンダリング時の (xsl:apply-templates および xsl:call-template を介した) テンプレートへの一連の呼び出しは、リストの種類、選択されているリストのビュー、ビューのスタイル、ビューに行グループが含まれているかどうかなど、さまざまな要因によって異なります。ここでは、以下の特性を持つリストが含まれるページにユーザーがアクセスした場合の、わかりやすい状況における最もシンプルな一連の呼び出しについて簡単に説明します。

  • リストの種類が 100 (汎用) である。

  • リストの BaseViewID が 1 である。

  • ビューのビュー スタイルは 0 (基本テーブル) である。

  • 行のグループがない。

XSLT スタイル シートのシステムは、ページの PreRender イベントによって呼び出されます。最上位の XSLT テンプレートは、以下の開始タグによって vwsytles.xsl で宣言された名前がないテンプレートです。

<xsl:template match="/">

このテンプレートの動作は Boolean テストの結果によって決まりますが、最もわかりやすい状況では、xsl:apply-templates を呼び出すことで、RootTemplate モードのテンプレートを呼び出して、ソース ノード ツリーのルートである現在のコンテキスト ノードを選択します (XmlDefinition 変数は、main.xsl で "."、つまり現在のコンテキスト ノードとして定義されています)。

<xsl:apply-templates mode="RootTemplate" select="$XmlDefinition"/>

これにより、View_Default_RootTemplate テンプレートが、"ドキュメント要素"、つまりソース コード ツリーの最上位要素である View 要素に適用されます (例については、「XSLT 変換での入力と結果ノード ツリーの例」を参照してください)。このテンプレートの開始タグを次に示します。

<xsl:template name="View_Default_RootTemplate" mode="RootTemplate" match="View" ddwrt:dvt_mode="root">

このテンプレートは、リストをレンダリングする HTML <table> 要素を作成します。また、以下の行を使用して補助テンプレートを呼び出します。

<xsl:apply-templates select="." mode="full">
  <!-- child node omitted --> 
</xsl:apply-templates>

この行は、xsl:applytemplates を呼び出すことで、full モードのテンプレートを呼び出し、現在のコンテキスト ノードを選択します。これは、この時点ではまだ View 要素です。ここで紹介する汎用リストの標準ビューのサンプル シナリオでは、一致するテンプレートは、vwsytles.xsl の View Templates セクションの最初のテンプレートだけです。この開始タグを次に示します。

<xsl:template match="View" mode="full">

このテンプレートは、リストの HTML 詳細のレンダリングを開始します。最も重要なのは、以下の行を使用して、追加のテンプレートが呼び出されるという点です。

<xsl:apply-templates select="." mode="RenderView" />

一致するテンプレートは、次の開始タグがあるテンプレートだけです。

<xsl:template match="View" mode="RenderView">

この名前のないテンプレートへの呼び出しは、重要な点で階層内の以前のテンプレートとは異なります。以前のテンプレートでは、リスト ビューを定義するソース ノード ツリーのみを情報のソースとして使用していました。しかし、リストをレンダリングする HTML テーブルに書き込むには、リストに含まれる項目 (行) の数、リスト内の特定のフィールドの値など、その特定のリストに関する情報が必要です。したがって、このテンプレートには、コンテンツ データベースの実際のリスト データが dsQueryResponse マークアップの形式で含まれる、thisNode という名前のパラメーターが渡されます。以降テンプレートを呼び出すか、または特定のモードのテンプレートを適用するたびに、これと同じパラメーターが、呼び出されたテンプレートに渡されます。thisNode パラメーターの内容の例については、「XSLT 変換での入力と結果ノード ツリーの例」を参照してください。

テンプレートは、thisNode のすべての行 (リスト項目) にループ処理を実行します。それぞれに対して、Item モードのテンプレートが適用され、そのテンプレートに、ビュー内のすべてのフィールドに対する参照が渡されます。重要な行をいくつか次に示します。

<xsl:for-each select="$AllRows">
  <xsl:variable name="thisNode" select="."/>
  <!-- Matter omitted. The next lines run when the view does not include groups --> 
    <xsl:apply-templates mode="Item" select=".">
      <xsl:with-param name="Fields" select="$Fields"/>
      <!-- matter omitted -->
    </xsl:apply-templates>
  <!-- matter omitted -->
</xsl:for-each>

AllRows 変数は、thisNode の Row 要素への参照です。現在のノード "." が、select 属性によって thisNode に割り当てられているように見えますが、実際のところ、これは thisNode 用にテンプレートに何も渡されなかった場合の、このパラメーターの既定値に過ぎません。実際は、dsQueryResponse マークアップがパラメーターとして渡されています。リスト内の行ごとに、Item モードのテンプレートが適用され、テンプレートには Fields パラメーターが渡されます。これは、ソース ノード ツリーのすべての FieldRef 要素に対する参照です。

Item モードのテンプレートが複数ありますが、リストの種類が 100 (汎用) で、ビュー スタイルが 0 のものは 1 つしかありません。それは、vwstyles.xsl の Row Templates セクションの最初のテンプレートです。この開始タグを次に示します。

<xsl:template mode="Item" match="Row">

このテンプレートは、現在のリスト項目のテーブルの行をレンダリングする <tr> 開始タグと終了タグを挿入します。そして、そのタグの間で、リスト項目にループ処理を実行し、printTbleCellEcbAllowed モードの各テンプレートに適用します。重要な行を次に示します。

<tr>

  <!-- matter omitted -->

  <xsl:for-each select="$Fields">

      <!-- matter omitted -->

      <xsl:apply-templates select="." mode="printTableCellEcbAllowed">
        <xsl:with-param name="thisNode" select="$thisNode"/>
      </xsl:apply-templates>

      <!-- matter omitted -->

  </xsl:for-each>

  <!-- matter omitted -->

</tr>

一致するテンプレートのみに次の開始タグが含まれます。

<xsl:template name="FieldRef_printTableCell_EcbAllowed" match="FieldRef" 
                   mode="printTableCellEcbAllowed" ddwrt:dvt_mode="body">

このテンプレートは、<td> 開始タグと終了タグを挿入し、現在のフィールドに対してテーブルのセルを形成します。また、カスケード スタイル シート (CSS) クラスをセルに割り当てます。ここで示すように、開始タグと終了タグの間では、PrintFieldWithECB モードのテンプレートを適用します。

<td>

  <!-- matter omitted -->

  <xsl:apply-templates select="." mode="PrintFieldWithECB">

  <!-- matter omitted -->

</td>

残りのすべてのテンプレートが階層内にあるように、関連する一致テンプレートはすべて fldtypes.xsl にあります。その開始タグは、次のコード ブロックの上部に示されます。このテンプレートと残りの一連のテンプレートは、現在の行がヘッダー行かデータ行かに基づいて、およびフィールド型 (Note、Currency など) やフィールドの基本型 (Text、Number など) に基づいて、HTML テーブルの特定のセルをレンダリングします。また、このレンダリングは、フィールドのレンダリング方法 (フィールドをプレーン テキストとしてレンダリングするか、表示フォームへのリンクとしてレンダリングするか) にも基づいています。以下のコードは、データ行の Text フィールドに対する残りのテンプレートの開始タグです。先行タスクによって、名前ごとに、または特定モードのテンプレートの適用結果としてそれぞれが呼び出されます。

<xsl:template name="FieldRef_NoMenu_PrintFieldWithECB" ddwrt:ECB="Menu" 
              match="FieldRef" mode="PrintFieldWithECB" ddwrt:ghost="always">

<xsl:template name="FieldRef_Ecb_PrintFieldWithDisplayFormLink" 
              ddwrt:ECB="Link" match="FieldRef[@LinkToItem]" 
              mode="PrintFieldWithDisplayFormLink" ddwrt:ghost="always">

<xsl:template name="FieldRef_PrintField" match="FieldRef" mode="PrintField" 
              ddwrt:dvt_mode="body" ddwrt:ghost="always">

<xsl:template name="PrintField" ddwrt:dvt_mode="body" ddwrt:ghost="always">

<xsl:template name="FieldRef_Text_body" ddwrt:dvt_mode="body" match ="FieldRef" 
              mode="Text_body">

最後のテンプレートは、ついに、HTML テーブルのセル内にある Text フィールドの値をレンダリングします。以下のコードは、このテンプレートのマークアップ全体を示しています。

<xsl:template name="FieldRef_Text_body" ddwrt:dvt_mode="body" match ="FieldRef" 
              mode="Text_body">
  <xsl:param name="thisNode" select="."/>
  <xsl:choose>
    <xsl:when test="@AutoHyperLink='TRUE'">
      <xsl:value-of select="$thisNode/@*[name()=current()/@Name]" 
                    disable-output-escaping ="yes"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$thisNode/@*[name()=current()/@Name]"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

URL のような文字列を HTML <a> リンクとして自動的に書式設定するようにフィールドが定義されているかどうかによって、テンプレートは分岐します。このような場合、XSLT プロセッサは、フィールド用の HTML をレンダリングするときに、"<" や "&" を重要な文字を同等の文字列エンティティ (&lt; や &amp;) で置き換えません。通常、対応する XSLT プロセッサではこの動作が既定で行われます。この複雑な動作を除くと、テンプレートは、以下の行でフィールドの値を単に生成します。

<xsl:value-of select="$thisNode/@*[name()=current()/@Name]"/>

この行の詳細については、「[方法] リスト ビューでのフィールドのレンダリングをカスタマイズする」を参照してください。

関連項目

概念

XSLT 変換での入力と結果ノード ツリーの例

その他の技術情報

リスト ビュー