<br>
<b>5.3 scripting.dictionary</b><b>对象</b><br>
许多microsoft的编程语言,如visual basic、vbscript和jscript,都提供集合(collection)。可以把集合想象为数组,可以使用其中内建的函数完成存储和操纵数据等基本任务。无须担心数据是在哪些行列,而是使用唯一的键进行访问。<br>
vbscript和jscript都提供类似的对象,通称scripting.dictionary对象或dictionary对象。它类似于二维数组,把键和相关条目的数据存放在一起。然而真正的面向对象的方法,不应直接访问数据条目,必须使用dictionary对象支持的方法和属性来实现。<br>
本章提供了一些示例页面,允许试验脚本运行期对象的方法和属性。这些实例在下载的文件的文件的chaper05子目录里。<br>
<br>
<b>5.3.1 </b><b>创建和使用dictionary</b><b>对象</b><br>
创建一个dictionary对象的示例如下:<br>
‘in vbscript:<br>
dim objmydata<br>
set objmydata = server.createobject(“scripting.dictionary”)<br>
<br>
//in jscript:<br>
var objmydata = server.createobject(‘scripting.dictionary’);<br>
<br>
<!-- server-side with an object element --><br>
<object runat=”server” scope=”page” id=”objmydata”<br>
progid=”scripting.dictionary”><br>
</object><br>
dictionary对象还可用于客户端的ie中。<br>
1. dictionary对象的成员概要<br>
表5-2和表5-3列出了dictionary对象的属性和方法及相应的说明。<br>
当增加一个键/条目对时,如果该键已存在;或者删除一个键/条目对时,该关键字/条目对不存在,或改变已包含数据的dictionary对象的comparemode,都将产生错误。<br>
表5-2 dictionary对象的属性和说明<table class=ubb cellspacing=0><tr><td class=ubb><br>
属 性</td><td class=ubb><br>
说 明</td></tr><tr><td class=ubb><br>
comparemode</td><td class=ubb><br>
(仅用于vbscript)设定或返回键的字符串比较模式</td></tr><tr><td class=ubb><br>
count</td><td class=ubb><br>
只读。返回dictionary里的键/条目对的数量</td></tr><tr><td class=ubb><br>
item(<i>key</i>)</td><td class=ubb><br>
设定或返回指定的键的条目值</td></tr><tr><td class=ubb><br>
key(<i>key</i>)</td><td class=ubb><br>
设定键值</td></tr></table><br>
表5-3 dictionary对象的方法和说明<table class=ubb cellspacing=0><tr><td class=ubb><br>
方 法</td><td class=ubb><br>
说 明</td></tr><tr><td class=ubb><br>
add(<i>key,item</i>)</td><td class=ubb><br>
增加键/条目对到dictionary</td></tr><tr><td class=ubb><br>
exists(<i>key</i>)</td><td class=ubb><br>
如果指定的键存在,返回true,否则返回false</td></tr><tr><td class=ubb><br>
items()</td><td class=ubb><br>
返回一个包含dictionary对象中所有条目的数组</td></tr><tr><td class=ubb><br>
keys()</td><td class=ubb><br>
返回一个包含dictionary对象中所有键的数组</td></tr><tr><td class=ubb><br>
remove(<i>key</i>)</td><td class=ubb><br>
删除一个指定的键/条目对</td></tr><tr><td class=ubb><br>
removeall()</td><td class=ubb><br>
删除全部键/条目对</td></tr></table><br>
2. 对dictionary中增加和删除条目<br>
一旦得到一个新的(空的)dictionary,可以对其添加条目,从中获取条目以及删除条目:<br>
‘ in vbscript:<br>
objmydata.add “mykey”, “myitem” ‘add value myitem with key mykey<br>
objmydata.add “yourkey”, ”youritem” ‘add value youritem with key yourkey<br>
blnisthere = objmydata.exists(“mykey”) ‘returns true because the item exists<br>
stritem = objmydata.item(“yourkey”) ‘retrieve value of yourkey<br>
stritem = objmydata.remove(“mykey”) ‘retrieve and remove yourkey<br>
objmydata.removeall ‘remove all the items<br>
在jscript中,等价的代码为:<br>
// in jscript;<br>
objmydata.add (‘mykey’, ‘myitem’); //add value myitem with key mykey<br>
objmydata.add (‘yourkey’, ‘youritem’); //add value youritem with key yourkey<br>
var blnisthere = objmydata.exists(‘mykey’); //returns true because the item exists<br>
var stritem = objmydata.item(‘yourkey’); //retrieve value of yourkey<br>
var stritem = objmydata.remove(‘mykey’); //retrieve and remove yourkey<br>
objmydata.removeall(); //remove all the items<br>
3. 修改键或条目的值<br>
可以通过修改键的值,或通过修改与特定的键关联的条目的数据,来改变存储在dictionary内的数据。下面的代码改变键为mykey的条目中的数据。<br>
objmydata.item(“mykey”) = “newvalue” ‘ in vbscript<br>
objmydata.item(‘mykey’) = ‘newvalue’; // in jscript<br>
如果指定的键在dictionary未找到,将在dictionary中创建一个以mykey为键,以new value为其条目值的新的键/条目对。有意思的是,如果使用一个不存在的键来检索条目,不仅得到一个空的字符串(这是可以想到的),而且还在dictionary里添加一个新的键/条目对,键即是指定的键,但条目的数据为空。<br>
可以使用key属性仅改变键的值而不改变与之对应的条目的数据。将一个已存在的键mykey改变为mynewkey,可以用:<br>
objmydata.key(“mykey”) = “mynewvalue” ‘ in vbscript<br>
objmydata.item(‘mykey’) = ‘mynewvalue’; // in jscript<br>
如果指定的键未找到,则产生运行期错误。<br>
4. 设置比较模式<br>
dictionary的comparemode属性仅适用于vbscript,不能在jscript中使用。当比较字符串键时,允许指定比较的方式。两个允许的值为binarycompare(0)和textcompare(1)。binarycompare(0)为二进制数对照(即区分大小写);textcompare(1)为文本对照(即不区分大小写)。<br>
5. 遍历dictionary<br>
研究dictionary时,有两个方法和一个属性需要特别注意,它们允许我们遍历存储在dictionary里的所有键/条目对。items方法用一个一维数组的形式返回dictionary里所有的条目数据,而keys方法用一个一维数组返回所有已存在的键值。可以使用count属性得到键或条目的数量。<br>
例如,可以使用下列代码得到名称为objmydata的dictionary中所有的键和条目值。注意,虽然count属性保存了在dictionary里的键/条目数量,但vbscript和jscript的数组总是从下标0开始的。因此,数组下标应从0到count-1。<br>
‘in vbscript:<br>
arrkeys = objmydata.keys ‘get all the keys into an array<br>
arritems = objmydata.items ‘get all the items into an array<br>
<br>
for intloop = 0 to objmydata.count –1 ‘iterate through the array<br>
strthiskey = arrkeys(intloop) ‘this is the key value<br>
strthisitem = arritems(intloop) ‘this is the item (data) value<br>
next<br>
<br>
// in jscript<br>
// get vb-style arrays using the keys() and items() methods<br>
var arrkeys = new vbarray(objmydata.keys()).toarray();<br>
var arritems = new vbarray(objmydata.items()).toarray();<br>
<br>
for (intloop = 0; intloop < objmydata.count; intloop++) {<br>
// iterate through the arrays<br>
strthiskey = arrkeys[intloop]; // this is the key value<br>
strthisitem = arritems[intloop]; // this is the item (data) value<br>
}<br>
在vbscript里也可以使用for each … next语句完成同样的功能:<br>
‘ iterate the dictionary as a collection in vbscript<br>
for each objitem in arritems<br>
response.write objitem & “ = “ & arritems(objitem) & “<br>”<br>
next<br>
<br>
<b>5.3.2 dictionary</b><b>对象示例</b><br>
本书提供了一系列示例文件可用来试验脚本运行时间库的各种属性。<br>
本章代码的缺省页面提供了一系列可使用的vbscript示例链接。有些示例对jscript同样有效。这些示例存放在chapter05目录下相应的子目录里,显示的界面如图5-2所示:<br>
<br>
图5-2 asp脚本运行期对象示例页面<br>
要查看dictionary对象的运行,在菜单页面点击第一个链接,打开名叫show_dictionary.asp的页面。这个页面显示了我们提供的dictionary对象的内容,允许试验其属性和方法。屏幕如图5-3所示:<br>
<br>
图5-3 dictionary对象的属性和方法<br>
1. dictionary的global.asa文件<br>
随dictionary对象示例页面提供的文件之一是global.asa。它创建并预先填充了一个会话层作用域的dictionary对象,因此其内容在页面请求之间不会丢失。一般说来(考虑到可扩展性),这不是一个理想的做法。在这个例子里,可以看到dictionary的属性和方法的效果。<br>
如果在自己的服务器上下载并安装示例,必须创建一个基于此global.asa文件的虚拟应用程序。或者将其内容添加到缺省站点的根文件夹中的global.asa文件里。在第3章讲述了如何用向导创建虚拟应用程序。然而对于本示例,创建一个虚拟应用程序最简单的方法是在chapter05示例文件夹内右击dictionary子文件夹,在properties对话框的home directory选项卡里,点击create按钮,如图5-4所示:<br>
<br>
图5-4 创建虚拟应用程序<br>
在这个global.asa文件里,代码使用<object>元素创建一个会话层作用域的scripting.dictionary对象实例。然后在session_onstart事件处理程序里将一系列值用add方法放入dictionary中,并将对dictionary对象的引用指定给asp会话变量mydictionary:<br>
<object id="objbooklist" runat="server" scope="session"<br>
progid="scripting.dictionary"><br>
</object><br>
<br>
<script language="vbscript" runat="server"><br>
<br>
sub session_onstart()<br>
objbooklist.add "2610", "professional active server pages 3.0"<br>
objbooklist.add "1274", "instant javascript"<br>
objbooklist.add "2882", "beginning asp components"<br>
objbooklist.add "1797", "professional asp techniques"<br>
objbooklist.add "1835", "ad0 2.0 programmer''s reference"<br>
set session("mydictionary") = objbooklist<br>
end sub<br>
<br>
</script><br>
2. dictionary示例页面<br>
在“scripting.dictionary object”主页面里,首要的任务是得到一个会话层作用域的dictionary对象实例的引用。注意,这个引用是一个对象变量,因此必须在vbscript里使用set关键字。<br>
然后,检查一下是否得到了一个对象(这是个好习惯),如果没有正确地建立包含global.asa文件的虚拟应用程序,检查一下问题出在哪里。你将看到我们自己的消息代替了asp的错误消息(但是注意,对于这一操作必须关闭缺省的错误处理)。<br>
<%<br>
<br>
on error resume next '' turn off error handling to test if object exists<br>
<br>
''retrieve dictionary object from user''s session<br>
set objmydata = session("mydictionary")<br>
<br>
if isobject(objmydata) then ''found dictionary object in session<br>
…<br>
%><br>
<br>
<p><div class="subhead">iterating the dictionary with arrays</div><br>
<%<br>
arrkeysarray = objmydata.keys ''get all the keys into an array<br>
arritemsarray = objmydata.items ''get all the items into an array<br>
for intloop = 0 to objmydata.count - 1 ''iterate through the array<br>
response.write "key: <b>" & arrkeysarray(intloop) & "</b> value: <b>" _<br>
& arritemsarray(intloop)& "</b><br>"<br>
next<br>
%><br>
…<br>
… other code and controls go here …<br>
…<br>
<%<br>
else<br>
<br>
''could not find dictionary object in the session<br>
response.write "dictionary object not available in global.asa for session"<br>
<br>
end if<br>
%><br>
显示在页面上的dictionary内容列表是使用dictionary对象的key和items方法创建的两个数组,可使用前面的代码遍历它们。<br>
3. dictionary页面控件<br>
在dictionary的内容列表下是一系列的html控件,可用于设定dictionary对象的某些属性和执行各种方法。这些控件全部在一个<form>内,其action属性值是本页面,所以窗体的内容提交回本页面。在前面的章节的示例里使用了同样的技术。<br>
在<form>段中,改变属性或执行一个方法是通过一个按钮(没有标题)实现的。用于属性和方法的值放入按钮旁的文本框或列表框中。<br>
该页的第一个按钮用于设定dictionary里的条目的key属性。这里使用了一个下拉列表,可以选择一个已经存在的key值。下面的代码创建了页面内该部分的控件。为了填充列表,使用了另外一个遍历dictionary对象的技术,即for each … next语句。代码如下:<br>
…<br>
<form action="<% = request.servervariables("script_name") %>" method="post"><br>
<br>
<p><div class="subhead">the dictionary properties</div><br>
<input type="submit" name="cmdchangekey" value=" "><br>
dictionary.key ("<br>
<select name="lstchangekey" size="1"><br>
<%<br>
for each objitem in objmydata<br>
response.write "<option>" & objitem<br>
next<br>
%><br>
</select> ") = "<br>
<input type="text" name="txtchangekey" size="15" value="new key name"> "<br>
<br><br>
…<br>
… other controls go here …<br>
…<br>
</form><br>
…<br>
4. 使用dictionary的属性和方法<br>
在“scription.dictionary object”页面,点击用来检查并改变条目的key属性的按钮,如图5-5所示:<br>
<br>
图5-5 使用dictionary的key属性<br>
把窗体再次提交给页面。该页面包含一个脚本段,检查被点击的按钮的值。它通过在resquest.form集合里查找按钮的名字来断定单击的是哪个按钮。如果发现一个对应于cmdchangkey的值,则从列表中或文本框中得到相应的值并用来改变key属性:<br>
…<br>
''look for a command sent from the form section buttons<br>
if len(request.form("cmdchangekey")) then<br>
strkeyname = request.form("lstchangekey") ''existing key from list box<br>
strnewkey = request.form("txtchangekey") ''new key value from text box<br>
objmydata.key(strkeyname) = strnewkey ''set key property of this item<br>
end if<br>
…<br>
页面重新载入后,在dictionary的内容列表里能看到相应的结果,如图5-6所示:<br>
<br>
图5-6 页面重载后的结果<br>
页面的其余代码用来设定一个条目的item属性,或者执行dictionary对象的方法。下面是这些操作的代码,每段代码与演示key属性的代码非常类似。每次都将结果显示在dictionary的内容列表中:<br>
…<br>
if len(request.form("cmdchangeitem")) then<br>
strkeyname = request.form("lstchangeitem") ''existing key from list box<br>
strnewvalue = request.form("txtchangeitem") ''new item value from text box<br>
objmydata.item(strkeyname) = strnewvalue ''set the item property<br>
end if<br>
<br>
if len(request.form("cmdadd")) then<br>
strkeyname = request.form("txtaddkey") ''new key value from text box<br>
stritemvalue = request.form("txtadditem") ''new item value from text box<br>
objmydata.add strkeyname, stritemvalue ''execute the add method<br>
end if<br>
<br>
if len(request.form("cmdremove")) then<br>
strkeyname = request.form("lstremove") ''existion key from list box<br>
objmydata.remove strkeyname ''execute the remove method<br>
end if<br>
<br>
if len(request.form("cmdremoveall")) then<br>
objmydata.removeall ''execute the removeall method<br>
end if<br>
…<br>
例如,如果现在点击add方法的按钮,在dictionary的内容列表里将增加一个新的条目,如图5-7所示:<br>
<br>
图5-7 增加一个新方法<br>
结果如图5-8所示:<br>
<br>
图5-8 add方法的结果<br>
可以在这个页面中试验dictionary对象的属性和方法,你将会发现什么因素及在什么环境下能引起dictionary对象错误。例如,尝试用与已经存在的一个条目相同的键值增加一个条目,看看会出现什么结果。
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器