Обзор систем отображения представлений списков с помощью XSLT-преобразований
Дата последнего изменения: 2 февраля 2011 г.
Применимо к: SharePoint Foundation 2010
В этом разделе приводится обзор системы отображения представлений списков в Microsoft SharePoint Foundation. Приступая к этой теме, необходимо иметь по крайней мере базовое представление о понятиях XSLT, включая таблицы стилей, шаблоны, параметры, деревья узлов и узлы контекста.
Отображение с помощью таблиц стилей XSLT
Таблицы стилей XSLT, которые поставляются с SharePoint Foundation, расположены XSL-файлах в папке %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\LAYOUTS\XSL. Два самых важных файла из них — это vwsytles.xsl и fldtypes.xsl. Первый содержит таблицы стилей для отображения списков вплоть до уровня строк. Второй содержит таблицы стилей для отображения конкретных полей, то есть ячеек, в представлениях списков. Большой набор глобальных переменных XSLT определен в файле main.xsl.
Таблица стилей XSLT анализирует исходное дерево узлов на некотором языке XML и выдает результирующее дерево узлов на другом языке XML. В простейшем случае исходное дерево преобразуется в результирующее. Это выполняется с помощью XSLT-шаблонов, каждый из которых представляет собой некоторое правило, определяющее способ преобразования определенного фрагмента исходной разметки во фрагмент результирующей разметки. Однако преобразование необязательно осуществляет простую переформулировку на результирующем языке только данных исходного дерева узлов. Оно может приводить к исключению данных из исходного дерева, а также вставлять в результирующее дерево данные, отсутствующие в исходном. В частности, XSLT-шаблон может объединять данные из нескольких входных деревьев узлов. Каждое дополнительное входное дерево узлов помимо исходного передается шаблону в виде параметра. У XSLT-шаблонов для отображения представлений списков в SharePoint Foundation имеется два входных дерева узлов:
source node tree — это разметка Схема View, в которой определяется текущее представление списка. Именно это дерево анализирует и обходит XSLT-процессор при построении результирующего дерева. Таким образом, в любой момент времени в ходе XSLT-преобразования контекстным узлом XSLT-процессора является узел в этой разметке.
Дерево параметра thisNode передается каждому шаблону визуализации XSLT с помощью вызова шаблона. Эта разметка содержит фактические данные из списка. При визуализации поля фактическое значение берется из этого параметра. Полную справку о разметке в параметре thisNode см. в статье XML-разметка dsQueryResponse.
Примеры этих деревьев узлов см. в разделе Примеры входного дерева узлов и результирующего дерева узлов в XSLT-преобразованиях.
Иерархия XSLT-шаблонов
Иерархия XSLT-шаблонов в SharePoint Foundation довольно сложна. Цепочка вызовов шаблонов (через 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 для шаблонов в полном режиме и выбирается текущий режим контекста, который на данном этапе все еще представляет собой элемент View. В рассматриваемом образце со стандартным представлением обычного списка единственным соответствующим шаблоном является первый из раздела View Templates файла vwsytles.xsl. У него следующий открывающий тег.
<xsl:template match="View" mode="full">
Этот шаблон начинает отображение некоторых HTML-данных для списка. Что более важно, он вызывает дополнительные шаблоны с использованием следующей строки.
<xsl:apply-templates select="." mode="RenderView" />
Единственным соответствующим шаблоном является шаблон со следующим открывающим тегом.
<xsl:template match="View" mode="RenderView">
Вызов этого неименованного шаблона отличается от предыдущих шаблонов в иерархии в одном важном отношении. В предыдущих шаблонах в качестве источника данных использовалось только исходное дерево узлов, которое определяет представление списка. Однако чтобы заполнить таблицу HTML, в которой будет отображаться список, необходимы сведения об этом конкретном списке, такие как число элементов (строк) в нем и значения конкретных полей в списке. Соответственно, этому шаблону передается параметр thisNode, в котором содержатся фактические данные списка из базы данных контента в виде разметки dsQueryResponse. При каждом последующем вызове шаблона или применении шаблонов к конкретному узлу этот же параметр передается вызываемым шаблонам. Пример содержимого параметра 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 является ссылкой на элементы Row в thisNode. Хотя кажется, что параметру thisNode назначается текущий узел "." с атрибутом select, это на самом деле только значение по умолчанию, которое имеет thisNode, если в шаблон для него не передается никакое другое значение. На самом деле в качестве параметра передается разметка dsQueryResponse. Для каждой строки в списке применяются шаблоны с режимом Item, которым передается параметр Fields. Последний является ссылкой на все элементы FieldRef в исходном дереве узлов.
Существует несколько шаблонов с режимом Item, но только один подходит для случая, когда список имеет тип 100 (общий) и его стиль представления равен 0. Это самый первый шаблон в разделе Row Templates файла vwstyles.xsl. У него следующий открывающий тег.
<xsl:template mode="Item" match="Row">
Этот шаблон вставляет открывающий и закрывающий HTML-тег <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">
Этот шаблон вставляет открывающий и закрывающий HTML-теги <td> для формирования ячейки таблицы для текущего поля. Он также назначает ячейке класс каскадных таблиц стилей (CSS). Между открывающим и закрывающим тегом он применяет шаблоны с режимом PrintFieldWithECB, как показано здесь.
<td>
<!-- matter omitted -->
<xsl:apply-templates select="." mode="PrintFieldWithECB">
<!-- matter omitted -->
</td>
Нужный соответствующий шаблон находится в файле fldtypes.xsl, как и все другие остальные шаблоны в иерархии. Его открывающий тег показан вверху следующего блока кода. Этот и остающиеся шаблоны в цепочке отображают определенные ячейки в таблице HTML в зависимости от того, является ли текущая строка строкой заголовка или данных, в зависимости от типа поля (например, Note или Currency) и базового типа поля (например, Text или Number) и необходимого способа отображения поля (например, в виде простого текста или в виде ссылки на форму отображения). Ниже приведены открывающие теги для оставшихся шаблонов для поля типа 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">
Последним является шаблон, который наконец отображает значение поля типа Text в ячейке таблицы HTML. Ниже приведена вся разметка для этого шаблона.
<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-разметку для поля, он не заменяет значимые символы, такие как "<" и "&" на эквивалентные им сущности (< и &), что совместимый XSLT-процессор обычно делает по умолчанию. Кроме этой ситуации шаблон просто вставляет значение поля с помощью следующей строки.
<xsl:value-of select="$thisNode/@*[name()=current()/@Name]"/>
Подробное рассмотрение этой строки см. в статье Инструкции. Настройка визуализации поля в представлении списка.
См. также
Концепции
Примеры входного дерева узлов и результирующего дерева узлов в XSLT-преобразованиях