ASP将XML模拟为RS的类
XML是个很好的东西,ASP本身很弱,但配合上一些强大的服务器对象,几乎可以无所不能。就比如我之前遇到的问题,ASP base64编码和解码,原生函数出来的结果总是有误差,但使用XML对象上的功能,就完美地解决问题了。
还有二进制内容的生成,ASP本身也是无法实现的(只能读取)。XML的很多优势,用在ASP中给ASP的效率和优美度都增添了光彩。
但这一次,我却想把XML模拟成ASP中另外的一个强大的对象 Recordset
对了,ASP缺了ADODB组件,基本上就瘫痪了。ADODB中的connection,recordset,stream都是ASP离不开的对象。深入查看下手册,会发现很多有用的东西。
下面这个,我就想把XML的读取,写入,筛选机制模拟成Recordset来操作。虽然功能上不是很理想,但基本操作流程都走通了。
这个XML用来作数据缓存很不错
本代码同步发表在开源中国:将XML数据模拟成Recordset对象的类
测试截图:
先帖测试代码(里面假定打开了一个数据库连接,conn,并有一个分类表news_class):
Dim Rs, tmp, i
Set Rs=New xmlRs
'Set tmp=Server.Create0bject("MSXML.DOMDocument")
'tmp.async=False
'tmp.load(Server.MapPath("/cache/News/newsclass.xml"))
'从DOMList打开
'Rs.Open tmp.documentElement.childNodes,True
'从记录集打开
'如果要直接保存xml文件,必须先指定路径
Rs.Path="a.xml"
Rs.Open conn.Execute("SELECT * FROM news_class"),True
'从文件打开
'Rs.Open "class.xml",True
Rs.Find "id>0"
Response.Write "本次查询到的记录数:"
Response.Write rs.Count&"<br />"
'注意.xpath中不可使用 <> 表示不等于,只能用 !=
'xPath运算符:http://www.w3school.com.cn/xpath/xpath_operators.asp
Dim startTime
startTime = Timer
For i = 0 To 100
Rs.Exec "SELECT * FROM table WHERE Id>0 AND className!='22' And lang='cn'"
Next
Response.Write "100次查询所耗时间:"& CCur(Timer - startTime)&" s<br />"
startTime = Timer
For i = 0 To 100
Rs.Exec "SELECT * FROM table WHERE Id>0 AND className!='22' And lang='cn' Order by classname asc, ID DESC"
Next
Response.Write "100次查询排序所耗时间:"& CCur(Timer - startTime)&" s<br />"
Response.Write "本次查询到的记录数:"
Response.Write rs.Count&"<br />"
'删除该行
'Rs.Delete
'Rs.Update
'call FindTest( rs)
'call OrderTest( rs)
call ReadTest( rs)
'call WriteTest( rs)
'call UpdateTest( rs)
'call ReadTest( rs)
'//=======测试函数==================//
Sub FindTest( rs)
Rs.Find "id>=2"
End Sub
Sub OrderTest( rs)
Rs.Order "id desc,classname desc"
End Sub
Sub ReadTest( rs)
rs.MoveFirst
Do Until Rs.EOF
Response.Write Rs("id")&";"
Response.Write Rs("classname")&";"
Response.Write Rs("enname")
Response.Write "<br />"
Rs.MoveNext
Loop
End Sub
Sub WriteTest( rs)
Dim i
i=0
Response.Write Rs.RecordCount &"<br />"
rs.MoveFirst
Do Until Rs.EOF
i = i + 1
Response.Write "原值:"
Response.Write Rs("id")&";"
Response.Write Rs("classname")&";"
Response.Write Rs("enname")
Response.Write "<br />"
Rs("id") = i
Rs("classname") = Rs("classname") & i
Rs("enname") = Rs("enname") &i
Response.Write "新值:"
Response.Write Rs("id")&";"
Response.Write Rs("classname")&";"
Response.Write Rs("enname")
Response.Write "<br />"
Rs.MoveNext
Loop
Rs.Update
End Sub
Sub UpdateTest( rs)
Rs.Exec "UPDATE [TABLE] SET [id]=1 , [classname]=222,[enname]='<我是 , 一个兵>'"
End Sub
Sub InsertTest( rs)
Rs.Exec "INSERT INTO [TABLE] ([id],[classname],[enname]) VALUES(1,'as''dddd','asd<>asdn')"
End Sub
'//=======测试函数 END==============//
下面是类原码(友情提示:代码中部分字符作了替换,使用时需要替换回原英文字符,原因是服务器有特殊字符过滤)
'====================================
' 类名: xmlRs
' 用途: 将XML数据模拟成Rs数据操作
' 作者: shirne
' 网址: http://www.shirne.com
' 说明: 操作完成调用update才可以更新到文件
' 1.字段筛选的功能暂未实现
' 2.排序效率不太好,一般不要用
' 3.更新或插入语句中只支持简单赋值
' 更新: 2012/12/20
'====================================
Class xmlRs
Private DOM 'XML文档对象
Private DOMList '数据列表
Private pPosition '指针位置
Private pCount '记录数
Private pBOF '是否超出开始
Private pEOF '是否超出结尾
Private pState '状态
Private pPath '对应的文件路径
Private xPath '查询条件的xPath格式
Public IDStr '创建的DOM类型,默认为MSXML2.DOMDocument,可以设定为其它类型
Public DBName '根节点的名称
Public TblName '行节点的名称
Public Charset '编码
Public currentNode '当前节点,如果调用了AddNew,则是新创建的节点
Private Field '字段(一个XML节点对象)
Private ph '字符串占位符
Public SQLMode 'SQL语句解析模式(True 严格解析)
Private Sub Class_Initialize
pCount = 0
pBOF = True
pEOF = True
pState = 0
pPosition= 0
DBName = "data"
TblName = "table"
Charset = "utf-8"
ph = Chr(0)
SQLMode= True
xPath = ""
'MSXML3.DOMDocument
'MSXML2.FreeThreadedDOMDocument
IDStr = "MSXML2.DOMDocument"
End Sub
Private Sub Class_Terminate
Set DOM=Nothing
Set currentNode=Nothing
If IsArray(DOMList) Then Erase DOMList
End Sub
'xml对象或路径,是否创建文件
Public Function Open(xml, create)
Set DOM = Server.Create0bject(IDStr)
DOM.async = False
Select Case TypeName(xml)
Case "String"
If InStr(xml,"<")>0 Then
If Not DOM.LoadXML(xml) Then
ErrRaise 5,"xmlRs.Open:错误的XML代码"
End If
Else
Path = xml
If Not DOM.Load(pPath) Then
If create Then
DOM.LoadXML("<?xml version=""1.0"" encoding="""& Charset &"""?><"& DBName &" />")
Else
ErrRaise 5,"xmlRs.Open:错误的文件路径"
End If
Else
create=False '从文件打开的,不用再次保存
End If
End If
Call setList
Case "DOMDocument"
Set DOM = xml
Call setList
Case "IXMLDOMElement"
DOM.LoadXML("<?xml version=""1.0"" encoding="""& Charset &"""?><"& DBName &" />")
DOM.documentElement.appendChild(xml)
Call setList
Case "IXMLDOMNodeList"
DOM.LoadXML("<?xml version=""1.0"" encoding="""& Charset &"""?><"& DBName &" />")
DOM.documentElement.appendChild(xml)
Call setList
Case "Recordset"
DOM.LoadXML("<?xml version=""1.0"" encoding="""& Charset &"""?><"& DBName &" />")
Call DataToXML(xml)
Case Else
ErrRaise 5,"xmlRs.Open:不支持的初始化数据类型:"& TypeName(xml)
End Select
If create Then
Call Update
End If
Call setProp
pState = 1
If pCount>0 Then TblName = currentNode.nodeName
End Function
'//获取和设置字段值,一律转换为小写
Public Default Property Get Item(key)
If pBOF Or pEOF Then Exit Property
Set Field=currentNode.selectSingleNode(LCase(key))
If Field Is Nothing Then
Item = Empty
Else
Item = Field.Text
End If
End Property
Public Property Let Item(key, val)
If pBOF Or pEOF Then Exit Property
Set Field=currentNode.selectSingleNode(LCase(key))
If Field Is Nothing Then
Set Field = DOM.createElement(LCase(key))
currentNode.appendChild(Field)
End If
If Not IsNull(val) Then
Field.Text = CStr(val)
End If
End Property
'//是否到达头部或尾部
Public Property Get BOF
BOF = pBOF
End Property
Public Property Get EOF
EOF = pEOF
End Property
'//获取和设定路径
Public Property Get Path
Path = pPath
End Property
Public Property Let Path(val)
If InStr(val,":")<1 Then
val = Server.MapPath(val)
End If
pPath = val
End Property
'//状态
Public Property Get State
State = pState
End Property
'//获取记录数
Public Property Get Count
Count = pCount
End Property
'//别名
Public Property Get RecordCount
RecordCount = pCount
End Property
'//获取记录集位置
Public Property Get Position
Position = pPosition
End Property
'//别名
Public Property Get AbsolutePosition
AbsolutePosition = pPosition
End Property
'//设置记录集位置
Public Property Let Position(val)
If val>0 And val<=pCount Then
pPosition = val
Set currentNode=DOMList(pPosition-1)
If pEOF Then
pEOF = False
End If
If pBOF Then
pBOF = False
End If
Else
ErrRaise 9,"xmlRs.Position:超出记录集"
End If
End Property
'//别名
Public Property Let AbsolutePosition(val)
Position = val
End Property
'//移动指定的行数
Public Sub Move( iNum)
If pBOF And iNum<0 Then
ErrRaise 5,"xmlRs.Move:指针已经超出记录头"
End If
If pEOF And iNum>0 Then
ErrRaise 5,"xmlRs.Move:指针已经超出记录尾"
End If
If iNum=0 Then Exit Sub
pPosition = pPosition+iNum
Call ChkProp
End Sub
'//移动到第一条记录
Public Sub MoveFirst
If pCount>0 Then pPosition = 1
Call ChkProp
End Sub
'//移动到最后一条记录
Public Sub MoveLast
pPosition = pCount
Call ChkProp
End Sub
'//移动到前一条记录
Public Sub MovePrevious
If pBOF=False Then
pPosition = pPosition-1
End If
Call ChkProp
End Sub
'//移动到下一条记录
Public Sub MoveNext
If pEOF=False Then
pPosition = pPosition+1
End If
Call ChkProp
End Sub
'//添加一条新的记录
Public Sub AddNew
Set currentNode = DOM.createElement(TblName)
DOM.documentElement.appendChild(currentNode)
pCount = pCount + 1
pPosition = pCount
pBOF = False
pEOF = False
End Sub
'//保存,对于已经指定路径的xml文件
Public Sub Update
If pPath = "" Then ErrRaise 5,"xmlRs.Update:路径设定不正确"
DOM.Save pPath
End Sub
'//可以指定路径保存
Public Sub Save( savePath)
If savePath<>"" Then Path = savePath
Call Update
End Sub
Public Function DataToXML( rs)
If rs.State<>1 Then ErrRaise 5,"xmlRs.DataToXML:记录集尚未打开"
Dim f
Do Until rs.EOF
AddNew
For Each f In rs.Fields
Item(f.Name) = f.Value
Next
rs.MoveNext
Loop
pPosition = 1
Call setList
End Function
'//执行sql
Public Function Exec( sql)
Dim objSQL, j
Set objSQL = SplitSQL(sql, SQLMode)
If objSQL("table")<>"" Then TblName = objSQL("table")
'测试分解后的sql
' Dim Fld,j
' For Each Fld In objSQL
' If IsArray(objSQL(Fld)) Then
' Response.Write Fld&":"
' For j=0 To UBound(objSQL(Fld))
' Response.Write objSQL(Fld)(j)&";"
' Next
' Response.Write "<br />"
' Else
' Response.Write Fld&":"& objSQL(Fld)&"<br />"
' End If
' Next
Select Case LCase(objSQL("type"))
Case "select"
Find objSQL("where")
Order objSQL("order")
Case "update"
Find objSQL("where")
Do Until pEOF
For j=0 To UBound(objSQL("field"))
Item(objSQL("field")(j))=objSQL("value")(j)
Next
MoveNext
Loop
Update
Case "insert"
AddNew
For j=0 To UBound(objSQL("field"))
Item(objSQL("field")(j))=objSQL("value")(j)
Next
Update
Case "delete"
Find objSQL("where")
Do Until pEOF
Call Delete
MoveNext
Loop
Case Else
ErrRaise 5,"xmlRs.Exec:SQL语句类型不正确"
End Select
End Function
'//查找,使用xPath原生方法查找,所以where语句仅支持xPath语法
Public Sub Find( wre)
If wre<>"" Then
xPath = "/"& DBName &"/"& TblName &"["& wre &"]"
Else
xPath = ""
End If
Call setList
Call setProp
End Sub
'//对结果进行排序,支持多个字段
Public Sub Order( odr)
If pCount<2 Then Exit Sub
If odr = "" Then Exit Sub
Dim prevVal, arrSort, i
If InStr(odr,"[")>0 Then
odr = Replace(Replace(odr,"[",""),"]","")
End If
arrSort = Split(odr,",")
'开始排序
'主排序
Dim sField, subField, objA, objB, a,b,j,k
sField = Split(Trim(arrSort(0))," ")
If UBound(sField)<1 Then
ReDim Preserve sField(1)
sField(1) = "ASC"
Else
sField(1) = UCase(sField(1))
End If
'字段名转换为小写
sField(0) = LCase(sField(0))
For j=0 To pCount-1
For k=j+1 To pCount-1
Set objA = DOMList(j).selectSingleNode(sField(0))
Set objB = DOMList(k).selectSingleNode(sField(0))
If objA Is Nothing Then
a = "0"
Else
a = objA.Text
End If
If objB Is Nothing Then
b = "0"
Else
b = objB.Text
End If
Select Case Compare(a,b)
Case 1
If sField(1) = "ASC" Then
Call Swap(j,k)
End If
Case -1
If sField(1) = "DESC" Then
Call Swap(j,k)
End If
Case 0
'主排序相等时启动副排序
For i=1 To UBound(arrSort)
If IsArray(arrSort(i))=False Then
subField = Split(arrSort(i)," ")
If UBound(subField)<1 Then
ReDim Preserve subField(1)
subField(1) = "ASC"
Else
subField(1) = UCase(subField(1))
End If
'字段名转换为小写
subField(0) = LCase(subField(0))
arrSort(i) = subField
End If
subField = arrSort(i)
Set objA = DOMList(j).selectSingleNode(subField(0))
Set objB = DOMList(k).selectSingleNode(subField(0))
If objA Is Nothing Then
a = "0"
Else
a = objA.Text
End If
If objB Is Nothing Then
b = "0"
Else
b = objB.Text
End If
'副排序有结果则退出,无则进行下一轮副排序
Select Case Compare(a,b)
Case 1
If subField(1) = "ASC" Then
Call Swap(j,k)
End If
Exit For
Case -1
If subField(1) = "DESC" Then
Call Swap(j,k)
End If
Exit For
End Select
Next
End Select
Next
Next
'重设属性
Call setProp
End Sub
Public Sub Delete
If pBOF Or pEOF Then Exit Sub
DOM.documentElement.removeChild(currentNode)
Call setList
Call setProp
End Sub
'解析SQL语句
'Param:sql 要解析的sql语句
'Param:sMode 是否执行严格解析,暂未支持
'允许有字符串的位置: 更新的值中
Public Function SplitSQL( oSql, sMode)
Dim L, i, ii, iA, iB, Rst, sql
oSql = Trim(oSql)
'清除与占位符冲突的字符,这里使用了两种占位符
If InStr(oSql,ph) Then oSql = Replace(oSql,ph,"")
If InStr(oSql,Chr(1)) Then oSql = Replace(oSql,Chr(1),"")
L = Len(oSql)
sql = oSql
If L < 6 Then ErrRaise 5,"xmlRs.SplitSQL:SQL语句错误"
Set Rst = Server.Create0bject("Scripting.Dictionary")
Rst.CompareMode = 1
'严格模式下将字符串替换为占位符
If sMode Then
For i=1 To L
i = InStr(i,sql,"'")
If i>0 Then
ii = InStr(i+1,sql,"'")
Do Until Mid(sql,ii+1,1)<>"'"
ii = InStr(ii+2,sql,"'")
If ii<1 Then
ErrRaise 5,"xmlRs.SplitSQL:SQL语句语法错误:"& Mid(oSql,i,20)
End If
Loop
sql = Left(sql, i) & String(ii-i-1,ph) & Mid(sql, ii)
i = ii
Else
Exit For
End If
Next
End If
'//规范化sql 去除多余空格,去除,两边的空格
'//严格模式下不会影响字符串中的内容
Call ClearSQL(sql, oSql)
L = Len(sql)
Rst.Add "type",Left(oSql,InStr(oSql," ")-1)
'查找各关键字的位置
Dim iTop, iWhere, iOrder, iSet, iValue, iTmp, iEnd, iFrom, iInto
'//前面加一个空格防止字段名有相同的(字段名是关键字就用[top])
iTop = InStr(1,sql," top",1)
iSet = InStr(1,sql," set",1)
iValue=InStr(1,sql," values",1)
iWhere=InStr(1,sql," where",1)
iOrder=InStr(1,sql," order by",1)
iFrom =InStr(1,sql," from",1)
iInto = InStr(1,sql," into",1)
Dim strFld, strVal, arrVal, iVal
Select Case LCase(Rst("type"))
Case "select"
If iTop>0 Then
iTmp = InStr(sql,iTop+4," ")
iEnd = InStr(iTmp+1,sql," ")
If iTmp<1 Or iEnd<1 Then
ErrRaise 5,"xmlRs.SplitSQL:SQL语句语法错误,"& Mid(oSql,iTop,40) &" 附近有语法错误"
End If
Rst.Add "top",Mid(oSql,iTop+4,iTmp-iTop-4)
Rst.Add "field",Mid(oSql,iTmp,iEnd-iTmp)
Else
iTmp = InStr(sql," ")+1
iEnd = InStr(iTmp+1,sql," ")
Rst.Add "field",Mid(oSql,iTmp,iEnd-iTmp)
End If
Rst.Add "table",Mid(oSql,iFrom+6,InStr(iFrom+6,sql," ")-iFrom-6)
Case "update"
Rst.Add "table",Mid(oSql,8,InStr(8,sql," ")-8)
If iSet<1 Then
ErrRaise 5,"xmlRs.SplitSQL:SQL语句语法错误,"& Mid(oSql,1,30) &" 缺少 SET"
End If
'取出字段及值
If iWhere>0 Then
arrVal = Split(Mid(sql, iSet+5,iWhere-iSet-5),",")
strVal = Mid(oSql, iSet+5,iWhere-iSet-5)
Else
arrVal = Split(Mid(sql, iSet+5),",")
strVal = Mid(oSql, iSet+5)
End If
Dim iEqal
iTmp = 1
For iVal=0 To UBound(arrVal)
iEnd = Len(arrVal(iVal))
arrVal(iVal)=Mid(strVal,iTmp,iEnd)
iTmp = iTmp + iEnd + 1
iEqal = InStr(arrVal(iVal),"=")
If iEqal<1 Then
ErrRaise 5,"xmlRs.SplitSQL:SQL语句语法错误,"& Mid(arrVal(iVal),1,30) &" 缺少 ="
End If
strFld = strFld& Mid(arrVal(iVal), 1, iEqal-1) & ","
arrVal(iVal)=Mid(arrVal(iVal),iEqal+1)
If InStr(arrVal(iVal),"'")=1 Then
arrVal(iVal)=Mid(arrVal(iVal),2,Len(arrVal(iVal))-2)
If InStr(arrVal(iVal),"''")>0 Then
arrVal(iVal) = Replace(arrVal(iVal),"''","'")
End If
End If
Next
strFld = Left(strFld,Len(strFld)-1)
If InStr(strFld,"[")>0 Then strFld=Replace(Replace(strFld,"[",""),"]","")
Rst.Add "field",Split(strFld,",")
Rst.Add "value",arrVal
Case "insert"
'取出表名
If iInto<1 Then ErrRaise 5,"xmlRs.SplitSQL:SQL语句语法错误,"& Mid(oSql,1,30) &" 缺少 INTO"
iTmp = InStr(iInto+6,sql,"(")
If iTmp<1 Then ErrRaise 5,"xmlRs.SplitSQL:SQL语句语法错误,"& Mid(oSql,iInto,30) &" 缺少 “(“ "
Rst.Add "table",Mid(oSql,iInto+6,iTmp-iInto-6)
'取出字段列表
iEnd = InStr(iTmp+2, sql, ")")
If iEnd<1 Then
ErrRaise 5,"xmlRs.SplitSQL:SQL语句语法错误,"& Mid(oSql,iInto+6,30) &" 缺少 “)”"
End If
strFld = Mid(sql,iTmp+1,iEnd-iTmp-1)
If InStr(strFld,"[")>0 Then strFld=Replace(Replace(strFld,"[",""),"]","")
Rst.Add "field",Split(strFld,",")
'取出值列表
If iValue<1 Then
ErrRaise 5,"xmlRs.SplitSQL:SQL语句语法错误,"& Mid(oSql,iEnd,30) &" 缺少 “VALUES”"
End If
iTmp = InStr(iValue, sql, "(")
iEnd = InStr(iTmp, sql, ")")
If iTmp<1 Or iEnd<1 Then
ErrRaise 5,"xmlRs.SplitSQL:SQL语句语法错误,"& Mid(oSql,iValue,30) &" 缺少 “(” 或 “)”"
End If
strVal = Mid(oSql, iTmp+1, iEnd-iTmp-1)
arrVal = Split(Mid(sql, iTmp+1, iEnd-iTmp-1),",")
If UBound(arrVal)<>UBound(Rst("field")) Then
ErrRaise 5,"xmlRs.SplitSQL:SQL语句语法错误,"& Mid(oSql,iTmp,30) &" 字段与值不对应"
End If
iTmp = 1
For iVal=0 To UBound(arrVal)
iEnd = Len(arrVal(iVal))
arrVal(iVal)=Mid(strVal,iTmp,iEnd)
iTmp = iTmp + iEnd + 1
If InStr(arrVal(iVal),"'")=1 Then
arrVal(iVal)=Mid(arrVal(iVal),2,Len(arrVal(iVal))-2)
If InStr(arrVal(iVal),"''")>0 Then
arrVal(iVal) = Replace(arrVal(iVal),"''","'")
End If
End If
Next
Rst.Add "value",arrVal
Case "delete"
If iFrom<1 Then ErrRaise 5,"xmlRs.SplitSQL:SQL语句语法错误,"& Mid(oSql,1,30) &" 缺少 FROM"
iTmp = InStr(iFrom+6,sql," ")
If iTmp<1 Then ErrRaise 5,"xmlRs.SplitSQL:SQL语句语法错误,"& Mid(oSql,iFrom,30) &" 附近有语法错误"
Rst.Add "table",Mid(oSql,iFrom+6,iTmp-iFrom-6)
Case Else
ErrRaise 5,"xmlRs.SplitSQL:SQL语句语法错误,错误的操作类型:"& Rst("type")
End Select
If InStr(Rst("table"),"[")=1 Then
Rst("table") = Mid(Rst("table"),2,Len(Rst("table"))-2)
End If
If iWhere>0 Then
If iOrder>0 Then
strFld = Mid(sql, iWhere + 7, iOrder - iWhere - 7)
strVal = Mid(oSql, iWhere + 7, iOrder - iWhere - 7)
Else
strFld = Mid(sql, iWhere + 7)
strVal = Mid(oSql, iWhere + 7)
End If
'兼容sql中的不等号
If InStr(strFld,"<>")>0 Then strFld = Replace(strFld,"<>","!=")
'主要是将字段名转换为小写
strFld = LCase(strFld)
iTmp = InStr(strFld,ph)
If iTmp>0 Then
Do Until iTmp<1
iEnd = InStr(iTmp,strFld,"'")
iVal = Mid(strVal,iTmp,iEnd-iTmp)
strFld = Left(strFld,iTmp-1) & Replace(strFld,Mid(strFld,iTmp,iEnd-iTmp),iVal,iTmp,1,0)
iTmp = InStr(iEnd,strFld,ph)
Loop
End If
Rst.Add "where",strFld
End If
If iOrder>0 Then
'排序的规则化将在排序功能内实现,这里只作取出
Rst.Add "order",Mid(sql, iOrder + 9)
End If
Set SplitSQL = Rst
End Function
Private Sub ClearSQL(sql, osql)
Dim Re, mth, m, l, v, i
Set Re = New RegExp
Re.Global = True
'清除多余空格
Re.Pattern = "\s+"
Set mth = Re.Execute(sql)
For Each m In mth
v = m.Value
i = m.FirstIndex
l = m.Length
If v<>" " Then
sql = Left(sql,i-1) & Replace(sql,v,String(l,Chr(1)),i,1,0)
osql = Left(osql,i-1) & Replace(oSql,v,String(l,Chr(1)),i,1,0)
End If
Next
Re.Pattern = "[\x01]+"
sql = Re.Replace(sql," ")
osql = Re.Replace(osql," ")
'清除逗号两边的空格
Re.Pattern = "\s*,\s*"
Set mth = Re.Execute(sql)
For Each m In mth
v = m.Value
i = m.FirstIndex
l = m.Length
If v<>" " Then
sql = Left(sql,i-1) & Replace(sql,v,String(l,Chr(1)),i,1,0)
osql = Left(osql,i-1) & Replace(oSql,v,String(l,Chr(1)),i,1,0)
End If
Next
Re.Pattern = "[\x01]+"
sql = Re.Replace(sql,",")
osql = Re.Replace(osql,",")
End Sub
'重新设定属性值
Private Sub setProp
If pCount>0 Then
pEOF = False
pBOF = False
If pPosition<1 Then
pPosition=1
ElseIf pPosition>pCount Then
pPosition=pCount
End If
Set currentNode=DOMList(pPosition-1)
Else
pEOF = True
pBOF = True
pPosition=0
Set currentNode=Nothing
End If
End Sub
'检查属性
Private Sub ChkProp
If pPosition<1 Then
pBOF = True
ElseIf pPosition>pCount Then
pEOF = True
Else
pBOF = False
pEOF = False
Set currentNode=DOMList(pPosition-1)
End If
End Sub
Private Sub setList
Dim DL, i
If xPath<>"" Then
Set DL = DOM.documentElement.selectNodes(xPath)
Else
Set DL = DOM.documentElement.childNodes
End If
pCount = DL.length
ReDim DOMList(pCount-1)
For i=0 To DL.length-1
Set DOMList(i) = DL(i)
Next
End Sub
'交换,用于排序
Private Sub Swap(a, b)
Dim tmp
Set tmp = DOMList(a)
Set DOMList(a) = DOMList(b)
Set DOMList(b) = tmp
End Sub
'比较,用于排序
Private Function Compare(a, b)
Compare = 0
If IsNumeric(a) And IsNumeric(b) Then
If CDbl(a)>CDbl(b) Then
Compare = 1
ElseIf CDbl(a)<CDbl(b) Then
Compare = -1
End If
ElseIf IsBool(a) And IsBool(b) Then
If a And Not b Then
Compare = 1
ElseIf b And Not a Then
Compare = -1
End If
Else
Compare = StrComp(a,b,1)
End If
End Function
'判断是否布尔值,并进行转换
Private Function IsBool(v)
IsBool = False
If StrComp(v,"true",1)=0 Then
v = True
IsBool = True
ElseIf StrComp(v,"false",1)=0 Then
v = False
IsBool = True
End If
End Function
Private Sub ErrRaise(code, Desc)
Err.Raise code, Desc
'Response.End()
End Sub
End Class