通常人们认为,符合COM接口规范的软件组件只能使用VB、C/C++这类语言开发。使用XML Scriptlet技术,我们可以用VBScript或JScript之类的脚本语言编写出完全符合COM接口规范的软件组件。本文为您介绍XML Scriptlet的基础概念,并通过实例说明在ASP环境下XML Scriptlet的编写和应用。
我们已经知道,XML Scriptlet是一种XML文件,其中包含了将本身描述为一个合格的COM自动化服务器的文本信息以及脚本代码。使得这种XML文件可以成为COM服务器的关键在于一个对所有XML Scriptlet都有效的公用运行时引擎。正是由于这个引擎的存在,我们才可以把XML Scriptlet直接看作是用VBScript或JScript编写的标准COM对象。
对于ASP开发者来说,由于以下两个原因这种脚本的模块化具有特殊的现实意义:
它提供了一种快速、巧妙地组件化、结构化传统ASP应用的方法,且无需借助于C/C++、VB这类“真正的”编程语言。
XML Scriptlet
所显露的编程接口是Web开发者所熟悉的基于对象的接口。
接下来,我们将通过一个您可能无数次面对的任务演示XML Scriptlet的应用:获取一个ADO记录集,并将结果显示为HTML表格。
㈠ 任务分析
显然,上述任务主要包含两部分操作。首先是从指定的数据源提取记录集;其次,将所获取的记录格式化成表格显示。在一般情况下,区分该任务的两个实例(两次不同的操作)仅需以下几个参数:
访问数据源的连接字符串;
提取数据的命令文本(
SQL查询,存储过程,等等);
应用于结果表格各个部分的
CSS样式;
要求显示的列及其标题、样式。
该任务的典型实现步骤包括:创建必须的ADO对象,执行提取数据的命令,遍历结果记录集并使用Response.Write输出结果表格。现假定我们面临的就是这样一个一般化的应用要求:尽可能地将代码封装进脚本组件,留下尽可能少的页面相关参数。接下来我们将介绍如何用XML Scriptlet来实现这个任务。
运行本文代码您需要安装最新版本的Scriptlet SDK,该SDK随同IE4.01 Service Pack 2 或IE5.0一起发布。它们都可以从http://windowsupdate.microsoft.com下载。
本文附带的代码包括ASP和SCT两类文件。其中SCT文件实现了两个将在下面具体讨论的脚本组件。在安装完Scriptlet SDK后,需要注册这些脚本组件。注册方法是在Windows资源管理器中右击该文件,选择“注册”。ASP文件是测试页面。示例代码假定系统中存在一个名为Contacts的DSN。
㈡ 提取记录集
首先我们来分析ServerGetNames.sct。该Scriptlet仅显露一个名为GetRecords()的方法。该方法要求两个参数:连接字符串conn和查询命令文本cmdText,它的返回值是一个ADO记录集,它的progID是“Server.GetContacts”。代码清单如下:
< ?XML version="1.0" encoding="GB2312" ?>
< scriptlet>
< registration
description="访问联系人数据库"
progid="Server.GetContacts"
version="1.00"
classid="{8D9CC880-D79F-11d2-B7C8-00C0DFE39736}">
< /registration>
< public>
< method name="GetRecords">
< parameter name="conn" />
< parameter name="cmdText" />
< /method>
< /public>
< implements type="ASP"/>
< script language="VBScript">
< ![CDATA[
Function GetRecords( conn, cmdText )
Dim rs
Set rs = CreateObject("ADODB.Recordset")
rs.CursorType = 3 'adOpenStatic
rs.Open cmdText, conn
Set GetRecords = rs
End Function
]]>
< /script>
< /scriptlet>
所有脚本函数的实现封装在一个CDATA块中,其目的是保证代码遵从XML 1.0规范。和所有普通COM自动化对象一样,该Scriptlet也提供了一个progID和CLSID。在GetRecords()中,程序通过ADO访问数据源,从而使得它可以访问任何OLE DB兼容数据源。由此,发送给GetRecords()的命令字符串可以是除了存储过程名字或SQL查询之外的其他命令。在注册这个Scriptlet之后,就可以编写使用这个Scriptlet的ASP页面了,请参见下载包中的GetNames.asp: < %
Set oData = CreateObject("Server.GetContacts")
Set rs = oData.GetRecords("Contacts", "select * from Contacts")
%>
可以看到,GetNames.asp中的结果记录集提取代码比通常用ADO获取记录集的代码更为简洁。然而,我们仍旧必须在ASP中格式化HTML表格(这部分代码这里没有显示),因此它还不是最好的方法。
㈢ 自动生成表格
进一步考虑上述Scriptlet,我们希望它能够自动格式化最终输出的表格,就象一个二进制设计时ActiveX控件一样。换句话说,我们希望Scriptlet能够直接返回一个字符串,这个字符串包含了一个经适当格式化的HTML表格。如果有了这样一个Scriptlet,则前面的ASP代码将成为:
< %
Set oData = CreateObject("Server.GetContacts")
Set rs = oData.GetRecords("Contacts", "select * from Contacts")
Set oPageMaker = CreateObject("Server.RSFormat")
oPageMaker.SetRS (rs)
strText = oPageMaker.GetText()
Response.Write strText
%>
这里的strText变量包含了一个代表所有结果记录的HTML表格字符串。为便于格式化表格内容及其外观,我们还为新的XML Scriptlet增加了几个属性和方法。完整代码请参见下载包中的ServerGetNames1.sct。下表是其接口说明:
方法
|
说 明
|
AddColumn(headerText, columnName, className)
|
在结果表格中加入一个列。必须在参数中指定列标题文本、列名字及其 CSS样式。
|
SetRS(rs)
|
指定要求格式化的记录集。
|
GetText()
|
返回可直接显示的结果字符串。
|
属性
|
说 明
|
TableStyle
|
设置整个表格的 CSS样式。
|
HeaderStyle
|
设置表格标题的 CSS样式。
|
NumberOfCols
|
设置表格总列数。必须在加入表格列之前调用该函数。
|
Title
|
设置在表格前显示的一个提示字符串。
|
显示结果记录集时只需设置总列数,依次加入各列即可。下面是新的GetText()函数的代码(参见ServerGetNames1.sct):
Function GetText()
Dim strText
' 设置标题
strText = m_Title + "(共"+ CStr(m_RS.RecordCount) +"人)< br>< br>" + vbCrLf
' 加入< TABLE>开始标记
strText = strText + "< TABLE class=" + m_TableStyle + ">" + vbCrLf
strText = strText + "< TR>" + vbCrLf
for i=1 to m_colCount
Dim strName
strText = strText + " < TH class=" + m_HeaderStyle + ">"
strText = strText + m_DispCols(i) + "< /TH>" + vbCrLf
next
strText = strText + "< /TR>" + vbCrLf
' 遍历记录集,添加表格行
while Not m_RS.EOF
strRowText = ""
for i=1 to m_colCount
Dim strClass
if VarType(m_ClssCols(i)) < > vbEmpty Then
strClass = "class=" + m_ClssCols(i)
end if
if VarType(m_RS(m_NameCols(i))) = vbNull Then
strColumn = " "
else
strColumn = m_RS(m_NameCols(i))
end if
' 格式化表格行
strRowText = strRowText + "< TD " + strClass + ">" + vbCrLf
strRowText = strRowText + strColumn + vbCrLf
strRowText = strRowText + "< /TD>" + vbCrLf
next
' 将表格行字符串加入strText
strText = strText + "< TR>" + strRowText + "< /TR>"
' 下一记录
m_RS.MoveNext
wend
GetText = strText
End Function
㈣ 最终的ASP页面
调用上述第二个Scriptlet的ASP页面为Getnames1.asp。该页面包含了一些CSS定义,获取和显示记录集的代码非常简单,如下所示:
Set oFormatter = CreateObject("Server.RSFormat")
oFormatter.SetRS (rs)
oFormatter.Title = "联系人列表"
oFormatter.TableStyle = "globTab"
oFormatter.HeaderStyle = "header"
oFormatter.NumberOfCols = 4
oFormatter.AddColumn "姓名", "姓名", ""
oFormatter.AddColumn "公司", "公司", "company"
oFormatter.AddColumn "电子邮件", "电子邮件", ""
strText = oFormatter.GetText()
可见,这个Scriptlet的应用过程和其他二进制COM对象是一样的,但实际上它们却是不同的:Scriptlet完全用XML和脚本写成!