熟悉MOSS开发的人都知道MOSS中提供了一种用来进行数据展示的Webpart,它可以让开发人员在不需要编写一行代码的基础上轻松地从List中取出数据,并以一定的格式将数据显示在页面上,这就是MOSS中用途非常广泛的DataView Webpart。默认的DataView Webpart总是以固定的格式显示数据,如按记录逐行显示数据、包含表格的标题栏、交替行背景色等。但是,我们可以使用XSLT来控制数据的显示样式,因为在MOSS中,List中的数据最终是以XML的形式存储在数据库中的,而DataView Webpart对XML数据进行了解析,并使用XSLT格式化了XML数据。当你使用Sharepoint Designer编辑一个Sharepoint页面时,你就可以看到DataView Webpart在页面上所使用的标记了,其中就包含了要格式化数据的XSLT代码,只要我们将符合要求的XSLT代码编辑好后替换上去,DataView Webpart就可以按照我们的方式来呈现数据。本文将结合实际例子讲解一下如何编辑DataView Webpart中的XSLT并按我们想要的方式呈现数据。
下图是一个MOSS网站的默认示例,默认情况下,当你安装完MOSS 2007后,总是可以通过IIS访问这个示例站点,为了节省创建Web Application和Site Collection的时间,我们直接用这个例子来进行演示。
图中给出了我们要实现的效果(即图中所标示的修改后的样式),为了以示区别,我将DataView Webpart原始的样子也显示出来了。我所采用的数据源就是当前站点下自带的Documents(其实Documents也是一种List),上图中标示为原始样式的区域就是该Documents中数据的默认显示样式。
好!现在让我们来看看如何实现数据显示样式的修改。
首先在Sharepoint Designer中打开当前站点下要编辑的页面,对本例而言就是根站点下的Default.aspx页面。如下图,将Documents拖放到页面上Webpart Zone所在的区域,DataView Webpart会默认将该Documents下的所有数据显示出来,并且只显示默认的几列,现在没有必要去修改这些设置,因为稍后我们会对其中的XSLT进行编辑,显示我们想要的数据。在Sharepoint Designer中添加完DataView Webpart后保存即可!
关闭打开的页面,在浏览器中刷新页面,将会看到我们在Sharepoint Designer中所做的修改,此时我们可以直接在页面上进行编辑。对本例而言,我们将上面一个DataView Webpart的XSLT代码拷贝出来进行编辑。事实上任何一种文本编辑器都可以编辑XSLT代码,但是我推荐使用Visual Studio,因为它不仅可以使代码格式看起来舒服,而且还提供了语法高亮显示和智能感知功能,你只需要在Visual Studio中新建一个xslt文件,将前面拷贝出来的代码粘贴进去就可以了。好,现在我们开始编辑XSLT代码。
下面是原始XSLT代码,我将它贴出来让读者进行参考。
1
<
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"
>
2
<
xsl:output
method
="html"
indent
="no"
/>
3
<
xsl:decimal-format
NaN
=""
/>
4
<
xsl:param
name
="dvt_apos"
>
'
</
xsl:param
>
5
<
xsl:param
name
="dvt_firstrow"
>
1
</
xsl:param
>
6
<
xsl:param
name
="dvt_nextpagedata"
/>
7
<
xsl:variable
name
="dvt_1_automode"
>
0
</
xsl:variable
>
8
9
<
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"
>
10
<
xsl:call-template
name
="dvt_1"
/>
11
</
xsl:template
>
12
13
<
xsl:template
name
="dvt_1"
>
14
<
xsl:variable
name
="dvt_StyleName"
>
Table
</
xsl:variable
>
15
<
xsl:variable
name
="Rows"
select
="/dsQueryResponse/Rows/Row"
/>
16
<
xsl:variable
name
="dvt_RowCount"
select
="count($Rows)"
/>
17
<
xsl:variable
name
="RowLimit"
select
="10"
/>
18
<
xsl:variable
name
="FirstRow"
select
="$dvt_firstrow"
/>
19
<
xsl:variable
name
="LastRow"
select
="$FirstRow + $dvt_RowCount - 1"
/>
20
<
xsl:variable
name
="IsEmpty"
select
="$dvt_RowCount = 0"
/>
21
<
table
border
="0"
width
="100%"
cellpadding
="2"
cellspacing
="0"
>
22
<
tr
valign
="top"
>
23
<
xsl:if
test
="$dvt_1_automode = '1'"
ddwrt:cf_ignore
="1"
>
24
<
th
class
="ms-vh"
width
="1%"
nowrap
="nowrap"
></
th
>
25
</
xsl:if
>
26
<
th
class
="ms-vh"
nowrap
=""
>
Name (for use in forms)
</
th
>
27
<
th
class
="ms-vh"
nowrap
=""
>
URL Path
</
th
>
28
<
th
class
="ms-vh"
nowrap
=""
>
Modified By
</
th
>
29
<
th
class
="ms-vh"
nowrap
=""
>
Modified
</
th
>
30
</
tr
>
31
<
xsl:call-template
name
="dvt_1.body"
>
32
<
xsl:with-param
name
="Rows"
select
="$Rows"
/>
33
<
xsl:with-param
name
="FirstRow"
select
="1"
/>
34
<
xsl:with-param
name
="LastRow"
select
="$dvt_RowCount"
/>
35
</
xsl:call-template
>
36
</
table
>
37
<
xsl:call-template
name
="dvt_1.commandfooter"
>
38
<
xsl:with-param
name
="FirstRow"
select
="$FirstRow"
/>
39
<
xsl:with-param
name
="LastRow"
select
="$LastRow"
/>
40
<
xsl:with-param
name
="RowLimit"
select
="$RowLimit"
/>
41
<
xsl:with-param
name
="dvt_RowCount"
select
="$dvt_RowCount"
/>
42
<
xsl:with-param
name
="RealLastRow"
select
="number(ddwrt:NameChanged('',-100))"
/>
43
</
xsl:call-template
>
44
</
xsl:template
>
45
<
xsl:template
name
="dvt_1.body"
>
46
<
xsl:param
name
="Rows"
/>
47
<
xsl:param
name
="FirstRow"
/>
48
<
xsl:param
name
="LastRow"
/>
49
<
xsl:for-each
select
="$Rows"
>
50
<
xsl:variable
name
="dvt_KeepItemsTogether"
select
="false()"
/>
51
<
xsl:variable
name
="dvt_HideGroupDetail"
select
="false()"
/>
52
<
xsl:if
test
="(position() >= $FirstRow and position() <= $LastRow) or $dvt_KeepItemsTogether"
>
53
<
xsl:if
test
="not($dvt_HideGroupDetail)"
ddwrt:cf_ignore
="1"
>
54
<
xsl:call-template
name
="dvt_1.rowview"
/>
55
</
xsl:if
>
56
</
xsl:if
>
57
</
xsl:for-each
>
58
59
</
xsl:template
>
60
<
xsl:template
name
="dvt_1.rowview"
>
61
<
tr
>
62
<
xsl:if
test
="position() mod 2 = 1"
>
63
<
xsl:attribute
name
="class"
>
ms-alternating
</
xsl:attribute
>
64
</
xsl:if
>
65
<
xsl:if
test
="$dvt_1_automode = '1'"
ddwrt:cf_ignore
="1"
>
66
<
td
class
="ms-vb"
width
="1%"
nowrap
="nowrap"
>
67
<
span
ddwrt:amkeyfield
="ID"
ddwrt:amkeyvalue
="ddwrt:EscapeDelims(string(@ID))"
ddwrt:ammode
="view"
></
span
>
68
</
td
>
69
</
xsl:if
>
70
<
td
class
="ms-vb"
>
71
<
xsl:value-of
select
="@FileLeafRef"
/>
72
</
td
>
73
<
td
class
="ms-vb"
>
74
<
a
href
="{@FileRef}"
>
75
<
xsl:value-of
select
="@FileRef"
/>
76
</
a
>
77
</
td
>
78
<
td
class
="ms-vb"
>
79
<
xsl:value-of
select
="@Editor"
disable-output-escaping
="yes"
/>
80
</
td
>
81
<
td
class
="ms-vb"
>
82
<
xsl:value-of
select
="ddwrt:FormatDate(string(@Modified), 1033, 5)"
/>
83
</
td
>
84
</
tr
>
85
</
xsl:template
>
86
<
xsl:template
name
="dvt_1.commandfooter"
>
87
<
xsl:param
name
="FirstRow"
/>
88
<
xsl:param
name
="LastRow"
/>
89
<
xsl:param
name
="RowLimit"
/>
90
<
xsl:param
name
="dvt_RowCount"
/>
91
<
xsl:param
name
="RealLastRow"
/>
92
<
table
cellspacing
="0"
cellpadding
="4"
border
="0"
width
="100%"
>
93
<
tr
>
94
<
xsl:if
test
="$FirstRow > 1 or $dvt_nextpagedata"
>
95
<
xsl:call-template
name
="dvt_1.navigation"
>
96
<
xsl:with-param
name
="FirstRow"
select
="$FirstRow"
/>
97
<
xsl:with-param
name
="LastRow"
select
="$LastRow"
/>
98
<
xsl:with-param
name
="RowLimit"
select
="$RowLimit"
/>
99
<
xsl:with-param
name
="dvt_RowCount"
select
="$dvt_RowCount"
/>
100
<
xsl:with-param
name
="RealLastRow"
select
="$RealLastRow"
/>
101
</
xsl:call-template
>
102
</
xsl:if
>
103
</
tr
>
104
</
table
>
105
</
xsl:template
>
106
<
xsl:template
name
="dvt_1.navigation"
>
107
<
xsl:param
name
="FirstRow"
/>
108
<
xsl:param
name
="LastRow"
/>
109
<
xsl:param
name
="RowLimit"
/>
110
<
xsl:param
name
="dvt_RowCount"
/>
111
<
xsl:param
name
="RealLastRow"
/>
112
<
xsl:variable
name
="PrevRow"
>
113
<
xsl:choose
>
114
<
xsl:when
test
="$FirstRow - $RowLimit < 1"
>
1
</
xsl:when
>
115
<
xsl:otherwise
>
116
<
xsl:value-of
select
="$FirstRow - $RowLimit"
/>
117
</
xsl:otherwise
>
118
</
xsl:choose
>
119
</
xsl:variable
>
120
<
xsl:variable
name
="LastRowValue"
>
121
<
xsl:choose
>
122
<
xsl:when
test
="$LastRow > $RealLastRow"
>
123
<
xsl:value-of
select
="$LastRow"
></
xsl:value-of
>
124
</
xsl:when
>
125
<
xsl:otherwise
>
126
<
xsl:value-of
select
="$RealLastRow"
></
xsl:value-of
>
127
</
xsl:otherwise
>
128
</
xsl:choose
>
129
</
xsl:variable
>
130
<
xsl:variable
name
="NextRow"
>
131
<
xsl:value-of
select
="$LastRowValue + 1"
></
xsl:value-of
>
132
</
xsl:variable
>
133
<
td
nowrap
=""
class
="ms-paging"
align
="right"
>
134
<
xsl:if
test
="$dvt_firstrow > 1"
ddwrt:cf_ignore
="1"
>
135
<
a
>
136
<
xsl:attribute
name
="href"
>
javascript:
<
xsl:value-of
select
="ddwrt:GenFireServerEvent('dvt_firstrow={1};dvt_startposition={}')"
/>
;
</
xsl:attribute
>
137
Start
</
a
>
138
<
xsl:text
disable-output-escaping
="yes"
ddwrt:nbsp-preserve
="yes"
>
&
nbsp;
</
xsl:text
>
139
<
a
>
140
<
xsl:attribute
name
="href"
>
javascript: history.back();
</
xsl:attribute
>
141
<
img
src
="/_layouts/images/prev.gif"
border
="0"
alt
="Previous"
/>
142
</
a
>
143
<
xsl:text
disable-output-escaping
="yes"
ddwrt:nbsp-preserve
="yes"
>
&
nbsp;
</
xsl:text
>
144
</
xsl:if
>
145
<
xsl:value-of
select
="$FirstRow"
/>
146
-
<
xsl:value-of
select
="$LastRowValue"
/>
147
<
xsl:text
xmlns:ddwrt
="http://schemas.microsoft.com/WebParts/v2/DataView/runtime"
ddwrt:nbsp-preserve
="yes"
disable-output-escaping
="yes"
>
&
nbsp;
</
xsl:text
>
148
<
xsl:if
test
="$LastRowValue < $dvt_RowCount or string-length($dvt_nextpagedata)!=0"
ddwrt:cf_ignore
="1"
>
149
<
a
>
150
<
xsl:attribute
name
="href"
>
javascript:
<
xsl:value-of
select
="ddwrt:GenFireServerEvent(concat('dvt_firstrow={',$NextRow,'};dvt_startposition={',$dvt_nextpagedata,'}'))"
/>
;
</
xsl:attribute
>
151
<
img
src
="/_layouts/images/next.gif"
border
="0"
alt
="Next"
/>
152
</
a
>
153
</
xsl:if
>
154
</
td
>
155
</
xsl:template
>
156
</
xsl:stylesheet
>
首先我们删掉不想显示的列,然后添加我们想要显示的列,并去掉默认添加的标题栏。另外,由于Documents中的数据太多而产生了分页,我们可以看到自动生成的代码中有很多是用来处理分页的,如果你不需要分页,你完全可以把这部分代码删掉。
默认情况下数据会在一列上显示,现在我们要将数据显示在两列上。查看DataView Webpart默认生成的XSLT,我们会发现数据都是显示在一个Table中的,那么要将一列数据显示为两列只需要在除第一行外的奇数行后面插入</tr><tr>标记即可。但是</tr><tr>标记不能直接写在XSLT代码中,因为如果这样的话XSLT认为代码中存在没有闭合的HTML标签而存在语法错误,所以我们只能通过变量来显示标签,并设置value-of的disable-output-escaping属性的值为yes将变量所指示的标签应用到页面上。下面是经过修改后的代码。
1
<
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"
>
2
<
xsl:output
method
="html"
indent
="no"
/>
3
<
xsl:decimal-format
NaN
=""
/>
4
<
xsl:param
name
="dvt_apos"
>
'
</
xsl:param
>
5
<
xsl:variable
name
="dvt_1_automode"
>
0
</
xsl:variable
>
6
<
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"
>
7
<
xsl:call-template
name
="dvt_1"
/>
8
</
xsl:template
>
9
10
<
xsl:template
name
="dvt_1"
>
11
<
xsl:variable
name
="dvt_StyleName"
>
Table
</
xsl:variable
>
12
<
xsl:variable
name
="Rows"
select
="/dsQueryResponse/Rows/Row"
/>
13
<
table
border
="0"
width
="100%"
cellpadding
="2"
cellspacing
="0"
>
14
<
xsl:call-template
name
="dvt_1.body"
>
15
<
xsl:with-param
name
="Rows"
select
="$Rows"
/>
16
</
xsl:call-template
>
17
</
table
>
18
</
xsl:template
>
19
20
<
xsl:variable
name
="strTrLeft"
select
="'<tr>'"
/>
21
<
xsl:variable
name
="strTrRight"
select
="'</tr>'"
/>
22
23
<
xsl:template
name
="dvt_1.body"
>
24
<
xsl:param
name
="Rows"
/>
25
<
xsl:value-of
select
="$strTrLeft"
disable-output-escaping
="yes"
/>
26
<
xsl:for-each
select
="$Rows"
>
27
<
xsl:call-template
name
="dvt_1.rowview"
/>
28
</
xsl:for-each
>
29
<
xsl:value-of
select
="$strTrRight"
disable-output-escaping
="yes"
/>
30
</
xsl:template
>
31
32
<
xsl:template
name
="dvt_1.rowview"
>
33
<
xsl:if
test
="position() > 1 and position() mod 2 = 1"
>
34
<
xsl:value-of
select
="$strTrRight"
disable-output-escaping
="yes"
/>
35
<
xsl:value-of
select
="$strTrLeft"
disable-output-escaping
="yes"
/>
36
</
xsl:if
>
37
<
td
>
38
<
IMG
BORDER
="0"
ALT
="{@FileLeafRef}"
title
="{@FileLeafRef}"
SRC
="/_layouts/images/{ddwrt:MapToIcon(string(@DocIcon), string(@DocIcon))}"
/>
39
</
td
>
40
<
td
class
="ms-vb"
>
41
<
a
href
="{@FileRef}"
target
="_blank"
>
42
<
xsl:value-of
select
="@FileLeafRef"
/>
43
</
a
>
44
</
td
>
45
</
xsl:template
>
46
</
xsl:stylesheet
>
有几个需要注意的地方:
1. 我们通过for-each循环$Rows变量中的数据,相当于逐行读取数据,我们对每一行数据进行格式化输出。position()函数作为for-each循环中的计数器,可以用来指示当前循环到第几条记录了。
2. 变量strTrLeft和变量strTrRight分别用来输出</tr>和<tr>,进行换行。注意value-of的disable-output-escaping属性的值。
3. 我们显示了Documents每条记录的两个字段的值,第一个是表示文档类型的图标,第二个是用来打开文档的超链接,注意一下其中的引用方法,尤其是如何获取文档类型的图标。
最后我们要做一个小的限制,那就是如果要显示的数据超过三行则只在页面上显示三行,并给出View More超链接。 其实这个就很简单啦,我们首先判断一下position()的值,如果大于6则不显示,然后根据条件在表格的末行显示一个View More得超链接就行了,下面是经过修改后的代码。
1
<
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"
>
2
<
xsl:output
method
="html"
indent
="no"
/>
3
<
xsl:decimal-format
NaN
=""
/>
4
<
xsl:param
name
="dvt_apos"
>
'
</
xsl:param
>
5
<
xsl:variable
name
="dvt_1_automode"
>
0
</
xsl:variable
>
6
<
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"
>
7
<
xsl:call-template
name
="dvt_1"
/>
8
</
xsl:template
>
9
10
<
xsl:template
name
="dvt_1"
>
11
<
xsl:variable
name
="dvt_StyleName"
>
Table
</
xsl:variable
>
12
<
xsl:variable
name
="Rows"
select
="/dsQueryResponse/Rows/Row"
/>
13
<
table
border
="0"
width
="100%"
cellpadding
="2"
cellspacing
="0"
>
14
<
xsl:call-template
name
="dvt_1.body"
>
15
<
xsl:with-param
name
="Rows"
select
="$Rows"
/>
16
</
xsl:call-template
>
17
</
table
>
18
</
xsl:template
>
19
20
<
xsl:variable
name
="strTrLeft"
select
="'<tr>'"
/>
21
<
xsl:variable
name
="strTrRight"
select
="'</tr>'"
/>
22
23
<
xsl:template
name
="dvt_1.body"
>
24
<
xsl:param
name
="Rows"
/>
25
<
xsl:value-of
select
="$strTrLeft"
disable-output-escaping
="yes"
/>
26
<
xsl:for-each
select
="$Rows"
>
27
<
xsl:if
test
="position() <= 6"
>
28
<
xsl:call-template
name
="dvt_1.rowview"
/>
29
</
xsl:if
>
30
<
xsl:call-template
name
="showmore"
>
31
<
xsl:with-param
name
="i"
select
="position()"
/>
32
</
xsl:call-template
>
33
</
xsl:for-each
>
34
<
xsl:value-of
select
="$strTrRight"
disable-output-escaping
="yes"
/>
35
</
xsl:template
>
36
37
<
xsl:template
name
="dvt_1.rowview"
>
38
<
xsl:if
test
="position() > 1 and position() mod 2 = 1"
>
39
<
xsl:value-of
select
="$strTrRight"
disable-output-escaping
="yes"
/>
40
<
xsl:value-of
select
="$strTrLeft"
disable-output-escaping
="yes"
/>
41
</
xsl:if
>
42
<
td
>
43
<
IMG
BORDER
="0"
ALT
="{@FileLeafRef}"
title
="{@FileLeafRef}"
SRC
="/_layouts/images/{ddwrt:MapToIcon(string(@DocIcon), string(@DocIcon))}"
/>
44
</
td
>
45
<
td
class
="ms-vb"
>
46
<
a
href
="{@FileRef}"
target
="_blank"
>
47
<
xsl:value-of
select
="@FileLeafRef"
/>
48
</
a
>
49
</
td
>
50
</
xsl:template
>
51
52
<
xsl:template
name
="showmore"
>
53
<
xsl:param
name
="i"
/>
54
<
xsl:if
test
="$i = 6 + 1"
>
55
<
xsl:value-of
select
="$strTrRight"
disable-output-escaping
="yes"
/>
56
<
xsl:value-of
select
="$strTrLeft"
disable-output-escaping
="yes"
/>
57
<
td
align
="right"
colspan
="4"
class
="ms-vb"
>
58
<
a
href
="../Documents/Forms/AllItems.aspx"
target
="_blank"
>
View more
</
a
>
59
</
td
>
60
</
xsl:if
>
61
</
xsl:template
>
62
</
xsl:stylesheet
>
注意一下View More链接的地址!
其实整个过程非常简单。由于DataView Webpart自动生成的XSLT有其固定的格式,我们在自定义的时候可以在它的基础之上进行操作,如果对其中某些样式的使用方法不熟悉的话可以参考那些自动生成的标记的写法,如本例中的文档类型图标,我就是参考了DataView Webpart默认生成的标记。