動態
ASP本身不支援動態包含檔案,現在的動態包含是通過FSO把被包含的檔案合并到主檔案裡再運行。以下也有把形如<!--#includefile="filename.asp"-->的普通包含檔案方式稱作“傳統引用”,用函數實現的動態包含檔案稱作“動態引用”。常見的程式如下:
Functioninclude(filename)
Dimre,content,fso,f,aspStart,aspEnd
setfso=CreateObject("Scripting.FileSystemObject")
setf=fso.OpenTextFile(server.mappath(filename))
content=f.ReadAll
f.close
setf=nothing
setfso=nothing
setre=newRegExp
re.pattern="^s*="
aspEnd=1
aspStart=inStr(aspEnd,content,"<%")+2
dowhileaspStart>aspEnd+1
Response.writeMid(content,aspEnd,aspStart-aspEnd-2)
aspEnd=inStr(aspStart,content,"%>")+2
Execute(re.replace(Mid(content,aspStart,aspEnd-aspStart-2),"Response.Write"))
aspStart=inStr(aspEnd,content,"<%")+2
loop
Response.writeMid(content,aspEnd)
setre=nothing
EndFunction
使用範例:include("youinc.asp")
以上範例引自
但這處函數在處理補包含的檔案中還有包含檔案時就不靈了。我在以上函數的基礎上改進出來如下函數,在被包含檔案中還有普通的包含檔案<!--#includefile="filename.asp"-->也可正常運行。
Functionincludeconvert(oRegExp,strFilename,strBlock)
DimincStart,incEnd,match,oMatches,str,code
'用提取ASP代碼的相同方式提取出include部分的檔案名稱,其餘部分原樣輸出
code=""
incEnd=1
incStart=InStr(incEnd,strBlock,"<!--#include")+13 '要找個目標字串<!--#include正好是13個字元,所以要+13
DoWhileincStart>incEnd+12 '兩個引用間距最小就是連續的--><--#,incStart是從<!--#include起數13個字元,所以要比前一個incEnd要至少多13-1得到的>incEnd+12的條件
str=Mid(strBlock,incEnd,incStart-incEnd-13)
str=Replace(str,"""","""""") '把單個雙引號換成兩個雙引號
str=Replace(str,VbCr,"")
str=Replace(str,VbLf,"")
str=Replace(str,VbCrLf,"")
code=code&VbCrLf&"Response.Write"""&str&""""
incEnd=InStr(incStart,strBlock,"-->")+3
oRegExp.pattern="(w+)=""([^""]+)""" '匹配file="filename.ext"或virtual="virtualname.ext",捕捉類型及檔案名稱兩個子串
SetoMatches=oRegExp.Execute(Mid(strBlock,incStart,incEnd-incStart-3))
Setmatch=oMatches(0) '確定只有一組捕捉時,要得到這一組匹配的子串,可以這樣做,省去用ForEachmatchInoMatches……Next
code=code&include(Mid(strFilename,1,InStrRev(strFilename,"/"))&match.SubMatches(1)) 'Mid(filename,1,InStrRev(filename,"/"))是在被引用的子檔案名稱有路徑時,把路徑提取出來,加在子檔案中傳統引用的檔案名稱前面,以找到正確的開啟檔案路徑,因為動態引用時的檔案路徑是相對主檔案而言的。要第二個匹配子串用SubMatches(1)
incStart=InStr(incEnd,strBlock,"<!--#include")+13
Loop
str=Mid(strBlock,incEnd)
str=Replace(str,"""","""""") '把單個雙引號換成兩個雙引號
str=Replace(str,VbCr,"")
str=Replace(str,VbLf,"")
str=Replace(str,VbCrLf,"")
code=code&VbCrLf&"Response.Write"""&str&""""
includeconvert=code
EndFunction
Functioninclude(filename)
Dimre,content,fso,f,aspStart,aspEnd,code
Setfso=CreateObject("scripting.FileSystemObject")
Setf=fso.OpenTextFile(Server.MapPath(filename))
content=f.ReadAll
f.close
Setf=nothing
Setfso=nothing
code=""
aspEnd=1
aspStart=InStr(aspEnd,content,"<%")+2
Setre=newRegExp
DoWhileaspStart>aspEnd+1
'傳統引用<!--#inclde肯定是在ASP程式碼片段以外的,所以先轉。
code=code&includeconvert(re,filename,Mid(content,aspEnd,aspStart-aspEnd-2))
aspEnd=InStr(aspStart,content,"%>")+2
re.pattern="^s*=" '這段正則替換原來是把<%=str%>換回成標準的<%Response.Writestr%>
code=code&VbCrLf&re.replace(Mid(content,aspStart,aspEnd-aspStart-2),"Response.Write")'ASP塊前面再加斷行符號換行,以避免串連塊之間多個Response.Write在同一行的錯誤
aspStart=InStr(aspEnd,content,"<%")+2
Loop
code=code&includeconvert(re,filename,Mid(content,aspEnd))
Setre=nothing
include=code
EndFunction
方便起見,以上函數最終返回的是整合了包含檔案的整個ASP代碼,使用時還要再用Execute執行之,即使用時需要:Execute(include("file.asp"))。