在SharePoint Designer中插入DataForm以后,你会发现它的代码部分由四大部分组成:
1)DataSources:数据源,可以是单数据源,多数据源链接,SharePoint也提供了各种数据源控件(XML,web服务,数据库,等等)。进行SharePoint中单数据列表操作的时候,用的是SPDataSource控件,本篇文章会主要介绍这个控件,另外将简要说明一下多数据源链接,及其应用场景。
2)ParameterBindings:Web Part的所有参数就包含在这里面
3)DataFields:可在Web Part上显示的所有数据域
4)XSL:XSLT,把数据源的数据转换成你想要的显示样式
DataForm的工作过程一般是这样的:
1)DataForm Web Part会首先处理参数Parameter,数据源中可能含有参数,以筛选数据,XSLT里面也可能有一些参数需要赋值,Web部件会把ParameteBindings块中的所有参数赋值给数据源和XSLT里面ParameterKey相同的参数;
2)然后,DataForm Web Part把数据源对应的数据取出来返回的XML格式数据;
<update>我们在SharePoint Designer里面看见的筛选窗口一般就是用来筛选数据源的,它会修改SPDatasource的Selectcommand属性</update>
3)最后,利用XSLT把数据源转换并返回给客户端。
<update>
我们在SharePoint Designer里面看见的筛选窗口的高级XPath筛选则是XSLT层次的筛选。
也就是说数据源筛选先进行,然后XSLT在逐条数据进行筛选,XSLT的筛选在数据量大的时候可能会影响性能。所以,没有特别的需求最好筛选数据源,不用XPath。
</update>
------
下面介绍一些DataSources,ParameterBindings和XSL相关的一些信息以及有用的链接:
1)DataSources
SPDataSource这个web控件有多种数据源模式:ListItem(单个列表项), List(某个列表), CrossList(跨列表), ListofLists(列表集合,显示列表的信息), Webs(网站的信息)
关于SPDataSource控件的信息,SharePoint Designer Team有一篇很好的Blog:SPDataSource and Rollups with the Data View
如果在ListItem和List模式下,DataForm Web Part中的SPDataSource必须要包含DataFormParameter,DataFormParameter是一个独立的参数类,DataForm Web Part用这个参数来定位数据源列表,同时DataFormParameter也只识别特定的ParameterKey:ListID,ListItemId,ListName,WebUrl等。
如果是ListItem模式下,必须要有(ListID or ListName) and ListItemId参数。
如果是List模式下,必须要有ListID 或者ListName参数。
技巧:如果你要迁移部署定制好的页面的话,你一定要使用ListName参数来定位列表。原因很简单,列表名称在迁移后不会变,但是ListID是会变化的。
在CrossList,ListofLists和Webs模式下的时候,SPDataSource的SelectCommand的写法和SPSiteDataQuery的查询规则相似。比如用<Lists></Lists>可以选择所有的当前网站的列表,以下是一个列出所有当前网站列表的例子:
<WebPartPages:DataFormWebPart runat="server" AllowConnect="True" PartImageSmall="" MissingAssembly="Can't exported"
IsIncludedFilter="" ExportMode="All" ID="g_eea4c5ed_0ae5_498b_9840_32b8409212b8" AllowRemove="True" FrameState="Normal"
ConnectionID="00000000-0000-0000-0000-000000000000" DetailLink="" ExportControlledProperties="True" IsIncluded="True"
sVisible="True" AllowEdit="True" Dir="Default" SuppressWebPartChrome="False" ViewContentTypeId="" PageSize="-1" FrameType="Default"
DataSourceID="" UseSQLDataSourcePaging="True" AllowHide="True" AllowMinimize="True" ShowWithSampleData="False" HelpMode="Modeless"
ViewFlag="0" Title="test1" HelpLink="" Description="" PartOrder="2" AllowZoneChange="True" PartImageLarge="" NoDefaultStyle="TRUE"
__MarkupType="vsattributemarkup" __WebPartId="{EEA4C5ED-0AE5-498B-9840-32B8409212B8}" __AllowXSLTEditing="true" WebPart="true" Height="" Width="">
<DataSources> <SharePoint:SPDataSource runat="server" SelectCommand="<Lists></Lists>" DataSourceMode="ListOfLists"
UseInternalName="True" ID="dataformwebpart1"></SharePoint:SPDataSource> </DataSources> <ParameterBindings>
<ParameterBinding Name="dvt_apos" Location="Postback;Connection"/> <ParameterBinding Name="UserID" Location="CAMLVariable"
DefaultValue="CurrentUserName"/> <ParameterBinding Name="Today" Location="CAMLVariable" DefaultValue="CurrentDate"/>
<ParameterBinding Name="ListName" Location="QueryString(ListName)" DefaultValue="test1"/> </ParameterBindings>
<DataFields>@__spAlertTemplate,__spAlertTemplate;@__spAllowContentTypes,__spAllowContentTypes;@__spAllowDeletion,__spAllowDeletion;
@__spAllowMultiResponses,__spAllowMultiResponses;@__spAnonymousPermMask,__spAnonymousPermMask;@__spAnonymousPermMask64,__spAnonymousPermMask64;
@__spAudit,__spAudit;@__spAuthor,__spAuthor;@__spBaseTemplate,__spBaseTemplate;@__spBaseType,__spBaseType;@__spCanReceiveEmail,
__spCanReceiveEmail;@__spContentTypes,__spContentTypes;@__spContentTypesEnabled,__spContentTypesEnabled;@__spCreated,__spCreated;
@__spCurrentChangeToken,__spCurrentChangeToken;@__spDefaultView,__spDefaultView;@__spDefaultViewUrl,__spDefaultViewUrl;
@__spDescription,__spDescription;@__spDirection,__spDirection;@__spDraftVersionVisibility,__spDraftVersionVisibility;
@__spEffectiveBasePermissions,__spEffectiveBasePermissions;@__spEmailAlias,__spEmailAlias;@__spEnableAssignToEmail,__spEnableAssignToEmail;
@__spEnableAttachments,__spEnableAttachments;@__spEnableMinorVersions,__spEnableMinorVersions;@__spEnableModeration,__spEnableModeration;
@__spEnableSyndication,__spEnableSyndication;@__spEnableVersioning,__spEnableVersioning;@__spEventReceivers,__spEventReceivers;
@__spEventSinkAssembly,__spEventSinkAssembly;@__spEventSinkClass,__spEventSinkClass;@__spEventSinkData,__spEventSinkData;
@__spExcludeFromTemplate,__spExcludeFromTemplate;@__spFields,__spFields;@__spFirstUniqueAncestor,__spFirstUniqueAncestor;
@__spFlags,__spFlags;@__spForceCheckout,__spForceCheckout;@__spForms,__spForms;@__spHasExternalEmailHandler,__spHasExternalEmailHandler;
@__spHasUniqueRoleAssignments,__spHasUniqueRoleAssignments;@__spHidden,__spHidden;@__spID,__spID;@__spImageUrl,__spImageUrl;
@__spInternalName,__spInternalName;@__spItemCount,__spItemCount;@__spItems,__spItems;@__spLastItemDeletedDate,__spLastItemDeletedDate;
@__spLastItemModifiedDate,__spLastItemModifiedDate;@__spLists,__spLists;@__spMultipleDataList,__spMultipleDataList;
@__spOnQuickLaunch,__spOnQuickLaunch;@__spOrdered,__spOrdered;@__spParentWeb,__spParentWeb;@__spParentWebUrl,__spParentWebUrl;
@__spPermissions,__spPermissions;@__spProperties,__spProperties;@__spPropertiesXml,__spPropertiesXml;@__spReadSecurity,__spReadSecurity;
@__spReusableAcl,__spReusableAcl;@__spRoleAssignments,__spRoleAssignments;@__spRootFolder,__spRootFolder;@__spRootFolderUrl,__spRootFolderUrl;
@__spSchemaXml,__spSchemaXml;@__spSendToLocationName,__spSendToLocationName;@__spSendToLocationUrl,__spSendToLocationUrl;
@__spShowUser,__spShowUser;@__spTitle,__spTitle;@__spVersion,__spVersion;@__spViews,__spViews;@__spWorkflowAssociations,__spWorkflowAssociations;
@__spWriteSecurity,__spWriteSecurity;</DataFields> <Xsl> <xsl:stylesheet xmlns:x=http://www.w3.org/2001/XMLSchema
xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" version="1.0" exclude-result-prefixes="xsl msxsl ddwrt"
xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:asp=http://schemas.microsoft.com/ASPNET/20
xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:xsl=http://www.w3.org/1999/XSL/Transform
xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:SharePoint="Microsoft.SharePoint.WebControls" xmlns:ddwrt2="urn:frontpage:internal">
<xsl:output method="html" indent="no"/> <xsl:decimal-format NaN=""/> <xsl:param name="dvt_apos">'</xsl:param>
<xsl:param name="ListName">test1</xsl:param> <xsl:variable name="dvt_1_automode">0</xsl:variable> <xsl:template match="/"
xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d=http://schemas.microsoft.com/sharepoint/dsp
xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer=http://schemas.microsoft.com/WebParts/v2/DataView/designer
xmlns:SharePoint="Microsoft.SharePoint.WebControls"> <xsl:call-template name="dvt_1"/> </xsl:template>
<xsl:template name="dvt_1"> <xsl:variable name="dvt_StyleName">Table</xsl:variable>
<xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row[@__spTitle=$ListName]"/>
<xsl:variable name="dvt_RowCount" select="count($Rows)" />
<xsl:variable name="dvt_IsEmpty" select="$dvt_RowCount = 0" /> <xsl:choose>
<xsl:when test="$dvt_IsEmpty"> <xsl:call-template name="dvt_1.empty" />
</xsl:when> <xsl:otherwise><table border="0" width="100%" cellpadding="2" cellspacing="0">
<tr valign="top"> <xsl:if test="$dvt_1_automode = '1'" ddwrt:cf_ignore="1">
<th class="ms-vh" width="1%" nowrap="nowrap"></th>
</xsl:if><th class="ms-vh" nowrap="">__spTitle</th><th class="ms-vh" nowrap="">__spID</th></tr>
<xsl:call-template name="dvt_1.body"> <xsl:with-param name="Rows" select="$Rows"/>
</xsl:call-template> </table></xsl:otherwise> </xsl:choose>
</xsl:template> <xsl:template name="dvt_1.body"> <xsl:param name="Rows"/>
<xsl:for-each select="$Rows"> <xsl:call-template name="dvt_1.rowview"/> </xsl:for-each>
</xsl:template> <xsl:template name="dvt_1.rowview"> <tr> <xsl:if test="position() mod 2 = 1">
<xsl:attribute name="class">ms-alternating</xsl:attribute> </xsl:if><td class="ms-vb">
<xsl:value-of select="@__spTitle" /></td><td class="ms-vb">
<xsl:value-of select="@__spID" /></td> <xsl:if test="$dvt_1_automode = '1'" ddwrt:cf_ignore="1">
<td class="ms-vb" width="1%" nowrap="nowrap">
<span ddwrt:amkeyfield="ID" ddwrt:amkeyvalue="ddwrt:EscapeDelims(string(@ID))" ddwrt:ammode="view"></span>
</td> </xsl:if> </tr> </xsl:template>
<xsl:template name="dvt_1.empty"> <xsl:variable name="dvt_ViewEmptyText">Nothing</xsl:variable>
<table border="0" width="100%"> <tr> <td class="ms-vb">
<xsl:value-of select="$dvt_ViewEmptyText" /> </td> </tr>
</table> </xsl:template> </xsl:stylesheet></Xsl> </WebPartPages:DataFormWebPart>
多数据源
我们经常在SharePoint里面使用查阅项,但是当我们用SharePoint Designer定制列表的时候,我们会发现我们能得到的查阅项字段都是以;隔开的查阅字段字符串,当我们需要得到更多的查阅项目的信息的时候我们就需要用到多数据源了,在SharePoint Designer里面我们叫“链接源”,你创建完了可以看到数据源详细信息形如下图:
上图例中,Rating列表是对test1列表进行评分的列表,Rating查阅了test1的标题,然后在一个视图中我需要查看test1的标题,以及对应标题的项目的评分情况(并且要取出评分日期),如下:
代码如下:
<WebPartPages:DataFormWebPart runat="server" IsIncluded="True" FrameType="None" NoDefaultStyle="TRUE" ViewFlag="0" Title="D?¨oy?Y???"
__markuptype="vsattributemarkup" __WebPartId="{43FE3CE1-BF73-4433-91B7-4F3545D4B808}" id="g_43fe3ce1_bf73_4433_91b7_4f3545d4b808">
<DataSources><SharePoint:AggregateDataSource runat="server" IsSynchronous="false" SeparateRoot="true" id="dataformwebpart1">
<sources><SharePoint:SPDataSource runat="server" DataSourceMode="List" UseInternalName="true" selectcommand="<View></View>">
<SelectParameters><asp:Parameter Name="ListID" DefaultValue="{84363D4D-19AD-4C8E-9743-B5EB85A8AF08}"/><asp:Parameter Name="WebURL"
DefaultValue="/test/"/></SelectParameters><DeleteParameters><asp:Parameter Name="ListID" DefaultValue="{84363D4D-19AD-4C8E-9743-B5EB85A8AF08}"/>
<asp:Parameter Name="WebURL" DefaultValue="/test/"/></DeleteParameters><UpdateParameters><asp:Parameter Name="ListID"
DefaultValue="{84363D4D-19AD-4C8E-9743-B5EB85A8AF08}"/><asp:Parameter Name="WebURL" DefaultValue="/test/"/></UpdateParameters>
<InsertParameters><asp:Parameter Name="ListID" DefaultValue="{84363D4D-19AD-4C8E-9743-B5EB85A8AF08}"/>
<asp:Parameter Name="WebURL" DefaultValue="/test/"/></InsertParameters></SharePoint:SPDataSource>
<SharePoint:SPDataSource runat="server" DataSourceMode="List" UseInternalName="true" selectcommand="<View></View>">
<SelectParameters><asp:Parameter Name="ListID" DefaultValue="{71C39267-AEB8-4111-B00F-161AC8C65EC4}"/><asp:Parameter Name="WebURL"
DefaultValue="/test/"/></SelectParameters><DeleteParameters><asp:Parameter Name="ListID" DefaultValue="{71C39267-AEB8-4111-B00F-161AC8C65EC4}"/>
<asp:Parameter Name="WebURL" DefaultValue="/test/"/></DeleteParameters><UpdateParameters><asp:Parameter Name="ListID"
DefaultValue="{71C39267-AEB8-4111-B00F-161AC8C65EC4}"/><asp:Parameter Name="WebURL" DefaultValue="/test/"/></UpdateParameters>
<InsertParameters><asp:Parameter Name="ListID" DefaultValue="{71C39267-AEB8-4111-B00F-161AC8C65EC4}"/><asp:Parameter Name="WebURL"
DefaultValue="/test/"/></InsertParameters></SharePoint:SPDataSource> </sources>
<aggregate><concat name="data source"><datasource name="Rating" id="0" Type="SPList"/><datasource name="test1" id="1" Type="SPList"/>
</concat></aggregate></SharePoint:AggregateDataSource></DataSources>
<datafields>@Title,?à¨o¨?a;@test1,test1;@rating,rating;@ID,ID;@ContentType,?¨2¨¨Y¨¤¨¤D¨a;@Modified,DT??¨o?à??;@Created,??????§¨o?à??;
@Author,??????§??;@Editor,DT????;@_UIVersionString,????à?;@Attachments,???t;@File_x0020_Type,???t¨¤¨¤D¨a;
@FileLeafRef,??3? (¨??¨?¨2?à¨a|죤);@FileDirRef,??¤??;@FSObjType,????¨¤¨¤D¨a;@_HasCopyDestinations,??¨?D????????à¨o;@_CopySource,????????;
@ContentTypeId,?¨2¨¨Y¨¤¨¤D¨a ID;@_ModerationStatus,¨|¨??¨2?á??¨??;@_UIVersion,UI ????à?;@Created_x0020_Date,??????§¨o?à??;@FileRef,URL ??¤??;
@Choices,Choices;</datafields> <XSL><xsl:stylesheet xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:x=http://www.w3.org/2001/XMLSchema
xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" version="1.0" exclude-result-prefixes="xsl msxsl ddwrt"
xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:asp=http://schemas.microsoft.com/ASPNET/20
xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:xsl=http://www.w3.org/1999/XSL/Transform
xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:SharePoint="Microsoft.SharePoint.WebControls" xmlns:ddwrt2="urn:frontpage:internal">
<xsl:output method="html" indent="no"/> <xsl:decimal-format NaN=""/>
<xsl:param name="dvt_apos">'</xsl:param> <xsl:variable name="dvt_1_automode">0</xsl:variable>
<xsl:variable name="RatingRows" select="/dsQueryResponse/Rating/Rows/Row" />
<xsl:template match="/"> <xsl:call-template name="dvt_1"/> </xsl:template>
<xsl:template name="dvt_1"> <xsl:variable name="dvt_StyleName">Table</xsl:variable>
<xsl:variable name="Rows" select="/dsQueryResponse/test1/Rows/Row"/>
<xsl:variable name="dvt_RowCount" select="count($Rows)" />
<xsl:variable name="IsEmpty" select="$dvt_RowCount = 0" />
<xsl:variable name="dvt_IsEmpty" select="$dvt_RowCount = 0" /> <xsl:choose>
<xsl:when test="$dvt_IsEmpty">
<xsl:call-template name="dvt_1.empty" /> </xsl:when>
<xsl:otherwise><table border="0" width="100%" cellpadding="2" cellspacing="0">
<tr valign="top"> <xsl:if test="$dvt_1_automode = '1'" ddwrt:cf_ignore="1">
<th class="ms-vh" width="1%" nowrap="nowrap"></th> </xsl:if>
<th class="ms-vh" nowrap="" style="width: 227px">?à¨o¨?a</th>
<th class="ms-vh" nowrap="" style="width: 89px">DT????</th> <th class="ms-vh" nowrap="">Rating</th></tr>
<xsl:call-template name="dvt_1.body"> <xsl:with-param name="Rows" select="$Rows" />
</xsl:call-template> </table></xsl:otherwise> </xsl:choose>
</xsl:template> <xsl:template name="dvt_1.body">
<xsl:param name="Rows"/> <xsl:for-each select="$Rows">
<xsl:variable name="XPath"> <xsl:call-template name="dvt.xpath" />
</xsl:variable> <xsl:call-template name="dvt_1.rowview">
<xsl:with-param name="Pos" select="concat('_', ddwrt:Counter())" />
<xsl:with-param name="XPath" select="$XPath" />
</xsl:call-template> </xsl:for-each> </xsl:template>
<xsl:template name="dvt_1.rowview"> <xsl:param name="Pos" /> <xsl:param name="XPath" />
<tr> <xsl:if test="position() mod 2 = 1">
<xsl:attribute name="class">ms-alternating</xsl:attribute> </xsl:if>
<xsl:if test="$dvt_1_automode = '1'" ddwrt:cf_ignore="1"> <td class="ms-vb" width="1%" nowrap="nowrap">
<span ddwrt:amkeyfield="" ddwrt:amkeyvalue="string($XPath)" ddwrt:ammode="view"></span>
</td> </xsl:if> <td class="ms-vb" style="width: 227px">
<xsl:value-of select="@Title"/> </td>
<td class="ms-vb" style="width: 89px">
<asp:Label runat="server" id="ff1{$Pos}" text={@Editor}
__designer:bind="{ddwrt:DataBind('u',concat('ff1',$Pos),'Text','','',string($XPath),'@Editor')}" />
</td> <td class="ms-vb">
<xsl:call-template name="Rating">
<xsl:with-param name="title"><xsl:value-of select="@Title" /></xsl:with-param> </xsl:call-template>
</td></tr> </xsl:template> <xsl:template name="Rating"> <xsl:param name="title" />
<xsl:variable name="rowsnumber" select="count($RatingRows[@test1=$title])"/> <xsl:choose>
<xsl:when test="$rowsnumber=0"> Not rated yet! </xsl:when>
<xsl:otherwise> <xsl:for-each select="$RatingRows[@test1=$title]">
<strong><xsl:value-of select="@rating"/></strong><xsl:text disable-output-escaping="yes">
&nbsp;</xsl:text>(RateDate:<xsl:value-of select="ddwrt:FormatDate(string(@Created), 2052, 5)"></xsl:value-of>) </xsl:for-each>
</xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="dvt.xpath">
<xsl:for-each select="ancestor-or-self::*"><xsl:value-of select="concat('/node()[',count(preceding-sibling::node())+1,']')" />
</xsl:for-each> </xsl:template> <xsl:template name="dvt_1.empty">
<xsl:variable name="dvt_ViewEmptyText">Not Rated yet!</xsl:variable> <table border="0" width="100%">
<tr> <td class="ms-vb">
<xsl:value-of select="$dvt_ViewEmptyText" /> </td>
</tr> </table> </xsl:template></xsl:stylesheet></XSL> <parameterbindings>
<ParameterBinding Name="dvt_apos" Location="Postback;Connection"/>
<ParameterBinding Name="UserID" Location="CAMLVariable" DefaultValue="CurrentUserName"/>
<ParameterBinding Name="Today" Location="CAMLVariable" DefaultValue="CurrentDate"/>
</parameterbindings></WebPartPages:DataFormWebPart>
注意:其中RatingRows和Rating template是用来取评分信息的XSLT模板。
2)ParameterBindings
我们把我们在DataForm Web Part里面需要用到的所有的参数在这里面进行定义,这里的参数会被同时应用到DataForm的数据源和XSLT里面。DataForm Web Part让我们可以定义统一的参数。SPDataSource的Selectcommand可以包含参数,DataFormParameter的值可以来自参数,XSLT中的参数值也可以来自统一定义的参数。在DataForm中有提供了了定义参数的界面如下:
可以看到提供了5中参数来源,其中:
>> 控件:来自页面上的控件的值
>> 表单:这个在上一篇Blog中就是用了这种参数 [SharePoint Designer技巧-1]使用DataView与Form Web Part实现列表的关键字查询
>> 查询字符串:URL中的参数
3)XSL
XSL这个主要就是XSLT和XPath的东西了,要能很好的定制DataForm的话,需要比较熟练XSLT和XPath。
SharePoint提供了XSLT的扩展函数,相关信息:
SharePoint Data View Web Part Extension Functions in the ddwrt Namespace(虽然是2003的版本,但是可以参考)
SharePoint Data View Conditional Formatting based on user permissions (这个是关于WSS 3.0中一个新的扩展函数IfHasRights的详细说明,这个函数可以用于判断当前用户对列表有某种权限作为筛选数据的条件,实际中比较有用的一个扩展函数)
关于DataForm的话题还没有结束!
对数据显示的深入定制是我们的目的之一,我们的另一个目的是和显示的数据进行交互(定制分页,定制排序,定制分组),对数据进行操作(添加,修改,删除),利用DataForm提供的功能我们可以方便的定制编辑,添加页面。如果大家等不及我下一篇相关的文章的话可以先看看SharePoint Designer Team 的一篇关于用Javascript操作编辑和添加页面的字段控件的文章:Using Javascript to Manipulate a List Form Field