分类存档: Develop - 第12页

XSL中的运算符与变量名

昨天在写XSL模板的时候,在模板中使用了一个变量,结果在调试的时候却怎么也不行,我的变量名是$ItemCount,然后在模板中使用了这个变量 :

  • <xsl:value-of select="Tag[position() = $ItemCount-1]" />

在调试时却总是提示“无法解析到变量或参数 'ItemCount-1'的引用。变量或参数可能没有被定义,或它可能不在范围内。”,我就奇怪了,这名字明明是对的,怎么会有错呢,然后就又在变量定义的地方把变量名给复制过来,看看还是不是会出错,结果还是一样的错误。

这下郁闷了,懒得伺候了,把东西扔一边,玩去了~

今天想到这个事,再不行这个模板总是要写完的,于是又开了EditPlus,找到那一句,就在想怎么改它,突然脑子里来了一点点灵光,在减号的两边各加了一个半角空格,Firefox里打开,bingo!正确执行。

在解决了这个问题之后才想到,短划线也就是“-”在XML里是符合命令规范的,也就是说,我在写成“$ItemCount-1”的时候,XSL Parser 把“$ItemCount-1”认为是一个变量,而不会认为是一个表达式,因此,就会提示找不到变量,出错。

找到问题的原因所在,就好解决了,直接把减号给独立出来:

  • <xsl:value-of select="Tag[position() = $ItemCount - 1]" />

解决问题,继续写模板。

[ASP] 《在JScript中使用缓存技术》补遗

《在JScript中使用缓存技术》一文中,在JScript中实现了基于Application.StaticObjects的缓存技术,并且实现一个类用于缓存的操作,但在实际使用过程中仍需要注意一些问题。

在JScript的函数中,如果参数类型是number或者string,那么是按值传递的,但如果是object,那么就是按引用传递了。另外,数组在JScript中也是作为一个特殊的对象对待,因此,数组的类型也是object,同样是按引用传递的。

使用xbsCache类进行保存和获取数据操作即put和get时,不管是按值还是按引用,都没有问题,但是在使用过程中,对数据操作的效果由数据类型不同而不同。

如果数据是number或string类型的,那么在get数据时,返回值是按值的,也就是说,我们得到的数据是缓存数据的一份copy,对变量的操作并不会影响到缓存中的数据,例:

  • // code by xujiwei
  • // from www.xujiwei.cn
  • var myname="my name is xujiwei";
  • xbsCache.put("name",myname);
  • // 从缓存中获取name,值为"my name is xujiwei"
  • var myname2=xbsCache.get("name");
  • // 给myname2赋值"xujiwei"
  • myname2="xujiwei";
  • // 从缓存中获取name,值仍为"my name is xujiwei"
  • var myname3=xbsCache.get("name");

但是在数据类型为object的情况下,我们就需要注意,在从缓存中获取数据之后,我们得到的只是一个指向缓存数据的引用而已,并不是缓存数据的copy,因此,对数据的修改是直接影响到缓存的,例:

  • // code by xujiwei
  • // 


阅读全文 »

[ASP] 在JScript中使用缓存技术

在编写ASP程序时,通常为了提高ASP程序的运行效率及减少对数据库的连接和查询,会使用缓存技术来缓存一些需要从数据库读取的数据。而在ASP中实现缓存的方法常用的就是使用Application对象。在编写ASP程序时,我们有两种语言可以选择,分别是VBScript和JScript。

在使用VBScript时,我们可以用Application缓存数组来实现缓存,例:

  • Dim rs,arr
  • rs.Open conn,sql,1,1
  • arr=rs.GetRows()
  • Application.Lock()
  • Application("cache")=arr
  • Applicatoin.UnLock()

在VBScript里,数组是可以存到Application对象里的,但是如果ASP的语言选择为JScript的话,那么就有些不妙了,我们在使用Application储存一个数组时,会出现以下错误:

Application object, ASP 0197 (0x80004005)

Disallowed object use

Cannot add object with apartment model behavior to the application intrinsic object.

在微软的知识库可以找到具体原因如下:

JScript arrays are considered to be "Apartment" COM components. Only Component Object Model (COM) 



阅读全文 »

Firefox与IE兼容性:getAttribute的返回值类型

在改AJAXRequest的过程中,碰到了个问题,应该算是Firefox和IE之间的兼容性问题。

提交表单时,往往需要先对表单进行验证,而这个验证的过程一般是放在form标签的onsubmit属性中。

onsubmit一般是由浏览器在form的submit动作发生时自动触发,但是如果表单由我们自己来提交,比如在AJAX应用中,就是由我们自己写程序将表单转换成请求字符串,再通过XMLHttpRequest发送到服务器,那么如果在此同时不丢掉表单验证的话,就需要我们自己来获取onsubmit属性,并去处理它。

在获取属性时,为了保证兼容性,我用getAttribute来获取标签的属性值,但是发获取了onsubmit属性之后,发现在Firefox和IE中使用getAttribute("onsubmit")所返回的返回值类型是不同的。

测试代码如下:



阅读全文 »

使用VS2005调试ASP程序

很早之前就在PJ的blog上看到可以用VS2005调试ASP程序,但是没有写出具体的步骤,后来一次偶尔也让我找到了方法,但是一直没把它写出来,今天就把用VS2005调试ASP程序的方法写出来,希望对写ASP程序的朋友们有用。

首先需要说明的是,我所用的环境是Win2003+IIS6,PJ用的环境是Vista+IIS7+WPF,不过我想WPF应该是无关紧要的,主要是服务器支持服务端脚本调试。在此我以IIS6为例说明怎样开启服务端脚本调试。

先打开“Internet 信息服务(IIS)管理器”,找到要开启服务端脚本调试的网站,进入属性页,进入“主目录”选项卡,点击“应用程序设置”中的“配置”,进入应用程序配置,进入“调试”选项卡,选中“启用ASP服务端脚本调试(E)”,确定即可。

图片附件

配置完IIS之后,就需要用VS2005来调试程序了。当然安装VS2005是必须的步骤,这里就不多说了。

使用VS2005调试ASP程序可以在两种情况下使用,一是程序出错时调试,一是手工加载调试。

如果想在ASP程序出错时才用VS2005进行调试,那么可以在装完VS2005之后直接测试ASP程序,如果程序出现错误,会自动提示是否使用VS2005进行调试。

图片附件

一个测试ASP程序,a=1,b=0,因此会有除0的错误,提示是否使用VS2005调试,选择是,使用新实例,如果已经打开了VS2005,则也可以直接用已经存在的实例来调试

图片附件

错误信息,可以选择中断或者继续

图片附件

中断,光标停在出错行,下部用红框标出的是变量监视窗口,可以查看当前上下文中的变量

另一种情况是在还没出错的情况下进行调试,这时需要先在浏览器中访问过需要调试的文件,因为这样ASP代码才会载入内存,然后打开VS2005,选择菜单中“工具->附加到进程”,然后选择w3wp.exe,如果在进程列表中没有找到w3wp.exe,可能是因为你还没有运行过ASP程序。

图片附件

这时可以在左边看到内存中存在的脚本文件,可以选择要调试的文件打开,然后进行下断点之类的操作,从下图可以看出,我下了个断点在a=1,运行时程序停在了a=1这一行。

图片附件

如果没有看到脚本资源管理,可以用菜单“调试->窗口->脚本资源管理器”来打开,或者使用快捷键Ctrl+Alt+N。

至此,我们就可以使用VS2005来调试ASP程序了,相信这会在ASP程序开发过程中给大家带来很大的方便。

[ASP] 在JScript中使用RecordSet对象的GetRows方法

写ASP程序时,一般情况总是使用的VBScript,不过也不只是这一种选择,也可以用JScript。但在用JScript作为ASP的语言时,比用VBScript有一些小小的不方便,比如RecordSet的GetRows方法。

在ASP中操作数据库,一般都要用到RecordSet对象,如果注重程序效率的话,可能就会用到RecordSet对象的GetRows方法,把记录集对象转换成数组,而操作数组在速度上将比用RecordSet对象的MoveNext方法快很多,而且可以在取出数组后尽早释放RecordSet对象,从而减少资源的占用,这也是优化ASP性能的一个方法。

在VBScript里,用RecordSet.GetRows方法取到的是一个二维数组,里面的数据可以通过遍历数组的方式来取得。

假设现在有一个数据库,其中有一个表名为mytable,有3个字段,名称分别为id,first,second。

  • ' code by xujiwei
  • http://www.xujiwei.cn/
  • ' 定义变量
  • Dim conn,rs,data,recN,i
  • ' 连接数据库
  • Set conn=Server.CreateObject("ADODB.Connection")
  • conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" &_
  • Server.MapPath("data.mdb")
  • ' 获取记录集
  • Set rs=conn.Execute("SELECT id,first,second FROM mytable")
  • ' 获取数据数组
  • data=rs.GetRows()
  • ' 关闭记录集,释放对象
  • rs.Close()
  • Set rs=Nothing
  • ' 获取记录数
  • recN=UBound(data,2)
  • ' 循环输出数据
  • For i=0 To 


阅读全文 »

[JavaScript] setTimeout和setInterval的浏览器兼容性

无意中测试AJAXRequest浏览器兼容性的时候,发现AJAXRequest.update方法在某些情况下在IE里有问题,经过测试找到是setTimeout和setInterval的问题。

问题出现在当调用AJAXRequest.update方法时,如果带了更新间隔及更新次数,那么在IE下面就会出现问题,具体表现为带了更新间隔时是函数工作,带上更新次数时函数无法在更新指定次数后停止执行。

测试几个例子之后找到了问题所在,在IE里,setTimeout和setInterval是不支持参数传递的

演示地址:http://www.xujiwei.cn/demo/usetimer/

在Netscape的JavaScript参考中找到setTimeout的语法如下:

setTimeout

Evaluates an expression or calls a function once after a specified number of milliseconds elapses.

语法

setTimeout(expression, msec)

setTimeout(function, msec, arg1, ..., argN)

参数

expression  A string containing a JavaScript expression.

msec  A numeric value or numeric string, in 



阅读全文 »

设计的选择:window.onload or other

在网页设计中,总要用到一些动态效果,而这些效果之中,有一些是需要页面加载完成时才可以做的,比如要给页面中的每一个链接加上hover时的特效,那么就需要在页面的所有代码已经下载完毕时再进行特效,这样才能保证页面里的每一个链接都不会遗漏。如果这步工作放在head中,那么,做与不做一个样。

再者,现在网页设计讲究行为、结构、表现分离,比如在最近的一次改版中,我把我的blog侧边栏的展开与折叠的功能放在了JS中添加,并不是在源代码里直接设置onclick事件添加好的。因为函数调用不是直接直接而是后来添加的,我就要考虑什么时候来用JS添加侧边栏的展开与折叠了。

功能的添加函数所在的脚本放在了head区引入,当然不能在脚本里直接调用这个函数来进行功能的添加,因为那个时候边栏还没有加载,用document.getElementById会出现找不到对象的错误,然后边栏的展开与折叠功能就没有。

那么,从这一点知道,功能的添加是需要在要处理的内容已经加载完成的情况下才能添加

那什么时候侧边栏已经加载完毕了呢,许多人自然而然地就想到了window.onload。是的,在window.onload被调用时,整个页面已经加载完成,那么边栏也一定加载完毕,这个时候做添加onclick响应函数是肯定不会出现找不到对象的错误的。

<html>
<head>
<meta name="author" content="www.xujiwei.cn" />
<meta name="description" content="ue test from xujiwei" />
<title>ue test1</title>
<style type="text/css">
#blockHead {
background: blue; color: white; width: 300px; padding: 1em; cursor: pointer; border: 1px solid blue;
}
#blockContent {
border: 1px solid blue; width:


阅读全文 »

VBScript中变量作用域

下午在写程序的时候,碰到个变量重定义的问题,具体是在一个函数中的两个地方定义了相同的变量,两个变量分别放在IF语句的两部分中,本来以为这两次定义在语句中不同的块,应该没有影响,然而在运行中IIS却提示变量重定义,把重复定义去掉即正确。

解决了问题之后突然想到在Fdream的blog看过一篇文章《JavaScript变量无块级作用域》,似乎这两个是差不多的,在VBScript中变量同样没有块级作用域

再次去看了那篇文章之后我也做了下试验,得到结果:在VBScript中,函数中定义的变量的作用域是整个函数,而不是块级,不管这个变量是在函数中哪个位置定义的。因此,函数中一个变量不管在函数的哪个位置定义,它在整个函数中都可以使用。

下面用一些例子来说明这个问题。

Option Explicit
Sub foo()
Dim var
var="hello,world!"
MsgBox var
End Sub
Call foo()

下面的代码跟上面的代码等效,但是var的定义放在了函数的最后:

Option Explicit
Sub foo()
var="hello,world!"
MsgBox var
Dim var
End Sub
Call foo()

下面的例子说明变量不管在哪定义,在整个函数中都是可以使用的,当然如果把定义的位置放的特殊一点有利于代码的清晰,阅读起来比较方便,修改时也比较方便。

Option Explicit
Sub foo()
Dim var1
var1="YES"
MsgBox "var1: "&var1&vbCrLf&"var2: "&var2
IF var1="YES"



阅读全文 »

[ASP] 用Server.Transfer实现博客日志的永久链接

在许多博客日志阅读页面里的尾部都能看到一个永久链接,这个链接一般是持久在在的,即使博客程序换了,也可以用这个链接来访问原来的日志,而不会出现找不到页面的情况,这对于一个博客的确是一个比较实用的功能。

在修改blog程序时,也考虑了这个问题,决定也给我的博客日志加上永久链接功能。

IIS6中如果请求一个目录后面跟上参数时,会把这个参数传给默认文档,即如果请求我的博客首页http://www.xujiwei.cn/blog/?id=500,那么id=500将会传递给默认文档default.asp。利用这点就可以实现博客日志的永久链接了。当然了,这个永久链接是建立在博客目录不改变的情况下,如果目录改了,就需要另外处理了。

在ASP中可以利用Response.Redirect,其原理是服务器向客户端发送一个302 Object Moved的响应,然后客户端根据响应进行转向,但这个会增加额外的带宽开销,并且不利用搜索引擎收录,所以推荐使用Server.Transfer来转向。Server.Transfer则是直接停止当前脚本的执行,转而执行指定的脚本,并且当前的一些变量如会话等均可在新脚本里直接使用,而毋须再重新进行参数传递了,而Response.Redirect则不可以。

两种方法的另外一个比较明显的区别就是使用Response.Redirect客户端显示的URL会改变,而Server.Transfer则不会,使用Server.Transfer时客户端不会感到当前URL其实已经改变。其实这个区别也可以通过两种方法的调用方法来看出来,一个是Response.Redirect由客户端做出改变,而Server.Transfer则是由服务端做出改变。

了解了这些就可以开始做了,打开博客的默认文档,一般就是博客程序的首页,如default.asp、index.asp等,然后在其有输出内容之前加上以下代码:

<%IF Request.QueryString("id") Then Server.Transfer("article.asp")%>

当然了,article.asp是要根据博客程序来做相应改变的,id即为要做为永久链接时的参数,需要注意这个参数必须为article.asp所能识别的,即article.asp可以根据这个参数来显示日志,如果不行的话就要做相应的改变,即把article.asp中的参数名称改为id,或者把id改成其他名称。

ok,完成!其实这个东西是很简单的,这么大篇幅大都是废话,真正有用的就那么一句代码^_^。