- 浏览: 7456 次
- 性别:
- 来自: 郑州
最新评论
注:原文发表在本人博客解析原生ASP代码的模板引擎(完善版)
但上面的代码并非最终修正版,这里类原码是最终修正版
测试文件:
但上面的代码并非最终修正版,这里类原码是最终修正版
'+++++++++++++++++++++++++++++++++++ 'ASP编译类 '可按设定直接将ASP文件编译运行返回结果 '在原生ASP中用来生成静态文件,而不采用获取Http页面的方法 'shirne@126.com 'http://www.shirne.com '+++++++++++++++++++++++++++++++++++ Class xCompile Private Includes '预包含文件 Private Ignores '忽略的包含文件 Private OutFun '输出函数 Private strHtml '最终的HTML字符串 Private Params '参数,仅支持QueryString参数,生成静态不建议使用其它参数 Private FuncStr '定义的全局函数名 Private ParamStr Private Classes '已加载的类列表,ASP中类不能重复加载 Private Prepared Private arrStr '提取出的字符串数组 Private arrStrLength Private StrRep '占位符 Private EndRep Private ClearRep '值:True/False 'True:将在全局模式下执行代码,注意变量与当前文件的变量定义冲突 'False:将把最终代码封装进函数执行,注意其它函数体内不能使用全局变量 Public GlobalMode Private Sub Class_Initialize OutFun = Array("Response.Write") FuncStr = "Outer__Html__Str" ParamStr= "In_Param_Str" Set Classes=Server.CreateObject("Scripting.Dictionary") Classes.CompareMode=1 Set Params=new xDictionary Params.Init Request.QueryString Prepared = -1 GlobalMode = True arrStr = Split(Empty) arrStrLength = UBound(arrStr) StrRep = Chr(1) '字符串占位 EndRep = Chr(3) '结束动作占位 ClearRep=Chr(2) '清除占位 End Sub Private Sub Class_Terminate Classes.RemoveAll Set Classes= Nothing Set Params = Nothing End Sub Public Default Property Get Html Html = strHtml End Property '主要动作是处理预包含文件 Public Property Get Prepare If IsArray(Includes) Then Dim i,L:L=UBound(Includes) If Prepared>=L Then Exit Property For i=Prepared+1 To L Require Includes(i) Next Prepared = L End If End Property '添加/获取参数 Public Property Let Param(key, val) Params.Replace key,val End Property Public Property Get Param(key) Param = Params(key) End Property '添加预包含文件 Public Sub AddInclude( File) Includes = Merge(Includes,CheckTruePath(File)) End Sub '添加忽略文件 Public Sub AddIgnore( File) Ignores = Merge(Ignores,CheckTruePath(File)) End Sub '添加输出函数 Public Sub AddOutFun( Fun) OutFun = Merge(OutFun,Fun) End Sub '保存 Public Sub SaveTo( path) WriteFile path, strHtml End Sub '检查是否磁盘路径,返回磁盘路径,可接收数组 Private Function CheckTruePath( obj) Dim Fso Set Fso=Server.CreateObject("Scripting.FileSystemObject") If IsArray(obj) Then Dim i For i=0 To UBound(obj) If InStr(obj(i),":")<1 Then If obj(i)&""<>"" Then obj(i) = Fso.GetAbsolutePathName(Server.MapPath(obj(i))) End If Next CheckTruePath = obj Else obj = obj&"" If InStr(obj,":")>0 Then CheckTruePath = obj Else If obj<>"" Then CheckTruePath = Fso.GetAbsolutePathName(Server.MapPath(obj)) End If End If End Function '编译文件 Public Sub Compile(File) '读取文件内容 strHtml = ReadFile(File) If strHtml="" Then Exit Sub End If '包含文件 strHtml = Include(strHtml,File) '去除页面指令 strHtml = RegReplace("<%@[^>]+%\>",strHtml,"") '整理换行符 strHtml = Replace(strHtml,Chr(13)&Chr(10),Chr(13)) strHtml = Replace(strHtml,Chr(10),Chr(13)) strHtml = Replace(strHtml,Chr(13),vbCrLf) Dim arrHtml, i, j, k, l i = InStr(strHtml,"<%") If i>0 Then '存在ASP标签,则逐个解析 ReDim arrHtml(0) j = 0 k = 1 Do Until i<1 l = InStr(i+1,strHtml,"%\>") If l<1 Then Err.Raise 7,"ASP语法错误,不正确的闭合标签" ReDim Preserve arrHtml(j+1) arrHtml(j) = FuncStr &" = "& FuncStr &" &"""& StrRep &"""" PutString EscapeHtml(Mid(strHtml,k,i-k)) arrHtml(j+1)=Mid(strHtml,i+2,l-i-2) If Left(arrHtml(j+1),1)="=" Then arrHtml(j+1) = FuncStr &" = "& FuncStr &" &"& EscapeAsp(Mid(arrHtml(j+1),2)) Else arrHtml(j+1) = EscapeAsp(arrHtml(j+1)) End If j = j + 2 k = l + 2 i = InStr(l+1,strHtml,"<%") Loop '最后的html内容 ReDim Preserve arrHtml(j) arrHtml(j) = FuncStr &" = "& FuncStr &" &"""& StrRep &"""" PutString EscapeHtml(Mid(strHtml,l+2)) strHtml = Join(arrHtml,vbCrLf) '执行预包含文件 PrePare If GlobalMode Then strHtml = RestoreString( strHtml, 0) '传递参数到全局 Call GlobalParam '在全局执行,如果在库函数中使用了定义的全局变量,要这样运行 ExecuteGlobal "Dim "& FuncStr & vbCrLf & strHtml & vbCrLf strHtml = Eval(FuncStr) Else '过滤类 strHtml = FilterClass(strHtml) '过滤Sub strHtml = FilterSub(strHtml) '过滤Function strHtml = FilterFunction(strHtml) strHtml = RestoreString( strHtml, 0) '用一个函数包装执行,如果结构严谨,库函数中没有使用全局变量,用这种方式最好 ExecuteGlobal "Function "& FuncStr &"("& ParamStr &")" & vbCrLf & strHtml & vbCrLf &"End Function" strHtml = Eval(FuncStr&"(Params)") End If i = InStr(strHtml, EndRep) j = InStr(strHtml, ClearRep) If (i<j Or j<0) And i>0 Then 'Response.End在前 strHtml = Mid(strHtml, 1, i-1) ElseIf j>0 Then 'Response.Clear在前 If i>0 Then '隐含条件 i>j strHtml = Mid(strHtml, j+1, i-j-1) Else strHtml = Mid(strHtml, j+1) End If End If End If End Sub '清理处理后的内容 Sub Clear Dim i '去除前后空白字符 strHtml = xTrim(strHtml,Chr(32)&Chr(9)&Chr(10)&Chr(13)) '清除注释 strHtml = RegReplace("<!--[\s\S]*?-->",strHtml,"") '清除空行 strHtml = RegExpReplace("^\s*$","gm",strHtml,"") End Sub '执行预包含文件,忽略asp标签外的所有内容 Private Function Require(File) Dim html, absPath html = ReadFile(File) absPath = Mid(File,Len(Server.MapPath(ROOT & "/"))+1) html = Include(html,absPath) Dim arrHtml, i, j, k, l i = InStr(html,"<%") If i>0 Then '存在ASP标签,则逐个解析,否则忽略该文件 ReDim arrHtml(0) j = 0 k = 1 Do Until i<1 l = InStr(i+1,html,"%\>") If l<1 Then Err.Raise 7,"ASP语法错误,不正确的闭合标签" ReDim Preserve arrHtml(j+1) arrHtml(j) = "" '忽略所有非asp内容 arrHtml(j+1)=Mid(html,i+2,l-i-2) j = j + 2 k = l + 2 i = InStr(l+1,html,"<%") Loop ExecuteGlobal Join(arrHtml,vbCrLf) End If End Function Private Sub GlobalParam ExecuteGlobal "Dim "& ParamStr & vbCrLf Execute "Set "& ParamStr &"= Params" End Sub '将html代码替换成VBS字符串 Private Function EscapeHtml( html) If InStr(html,"""")>0 Then html = Replace(html,"""","""""") If InStr(html,vbCrLf)>0 Then html = Replace(html,vbCrLf,"""& vbCrLf &""") EscapeHtml = html 'Replace(html,Chr(0),"") End Function '重新编码ASP代码,替换输出函数,替换参数 Private Function EscapeAsp( html) Dim i '去除注释,以免影响下面替换 html = FilterComment(html) For i=0 To UBound(OutFun) '先替换带括号的,这里不够严谨,没有判断括号嵌套的情况 '其实后面带不带括号都可以看作一个整体,所以下面一个替换就好了 'If InStr(1,html,OutFun(i)&"(", 1)>0 Then ' html = RegReplace("\b"& OutFun(i) &"\(([^()]+?)\)",html,FuncStr &" = "& FuncStr &" & $1") 'End If If InStr(1,html,OutFun(i),1)>0 Then html = RegReplace("\b"& OutFun(i) &"\b",html,FuncStr &" = "& FuncStr &" &") End If Next If InStr(1,html,"Request.QueryString(",1)>0 Then html = RegReplace("\bRequest\.QueryString\(",html,ParamStr &"(") End If If InStr(1,html,"Response.End",1)>0 Then html = RegReplace("\bResponse\.End(\(\s*\))?",html,FuncStr &" = "& FuncStr &" &"""& EndRep &"""") End If If InStr(1,html,"Response.Clear",1)>0 Then html = RegReplace("\bResponse\.Clear(\(\s*\))?",html,FuncStr &" = "& FuncStr &" &"""& ClearRep &"""") End If EscapeAsp = html End Function '恢复ASP代码中的字符串 Private Function RestoreString(html, j) Dim i, iEnd, oHtml iEnd = 1 i=InStr(html,StrRep) Do Until i<1 '略过已恢复的 Do While IsEmpty(arrStr(j)) j = j + 1 If j>arrStrLength Then Exit Do Loop oHtml = oHtml & Mid(html, iEnd, i-iEnd) & arrStr(j) '已恢复的设为空 arrStr(j) = Empty iEnd = i + 1 i = InStr(iEnd, html, strRep) j = j + 1 If j>arrStrLength Then Exit Do Loop If iEnd>0 Then oHtml = oHtml & Mid(html, iEnd) RestoreString = oHtml End Function '包含入文件 Private Function Include(html,ByVal path) Dim Matches,Match,iHtml, iPath, oHtml, lastIndex Dim iStart, iEnd Set Matches=REObject("<!--\s*#include\s+(file|virtual)=""([^*?<>=:""|]+)""\s*-->","gi").Execute(html) If Matches.Count>0 Then lastIndex = 1 iStart = 1 iEnd = 1 For Each Match In Matches '存在asp标签,且asp结束标签在Match.FirstIndex之前,则查找下一组asp标签 '直到不存在asp标签或结束标签在Match.FirstIndex之后 '保证当前匹配到的包含语法不在asp标签内部 Do Until iStart<1 Or Match.FirstIndex<iEnd iStart = InStr(iEnd, html, "<%") If iStart>0 Then iEnd = InStr(iStart,html,"%\>") Loop If iStart<1 Or Match.FirstIndex<iStart Then oHtml = oHtml & Mid(html,lastIndex,Match.FirstIndex+1-lastIndex) If StrComp(Match.SubMatches(0),"file",1)=0 Then iPath = getDir(path) & Match.SubMatches(1) ElseIf StrComp(Match.SubMatches(0),"virtual",1)=0 Then iPath = Match.SubMatches(1) Else iPath = "" End If If CheckNeedInclude(iPath) Then iHtml = ReadFile(iPath) iHtml = Include(iHtml,iPath) oHtml = oHtml & iHtml End If Else oHtml = oHtml & Mid(html, lastIndex,Match.FirstIndex+Match.Length+1 - lastIndex) End If lastIndex = Match.FirstIndex+Match.Length+1 Next oHtml = oHtml & Mid(html, lastIndex) Include = oHtml Else Include = html End If End Function '检查是否需要包含 Private Function CheckNeedInclude(ByVal path) CheckNeedInclude = True If path="" Then CheckNeedInclude = False:Exit Function path = CheckTruePath(path) Dim i '先检查预包含文件 If IsArray(Includes) Then For i=0 To UBound(Includes) If StrComp(Includes(i),path,1)=0 Then CheckNeedInclude = False Exit Function End If Next End If '再检查忽略含文件 If IsArray(Ignores) Then For i=0 To UBound(Ignores) If StrComp(Ignores(i),path,1)=0 Then CheckNeedInclude = False Exit Function End If Next End If End Function '移除注释,并提取字符串 Private Function FilterComment( html) Dim intStart, intEnd, intQuot, intPos, ohtml, L L = Len(html) intPos = 1 Do While intPos < L And intPos>0 intQuot=InStr(intPos,html,"'") intStart=Instr(intPos,html,"""") If (intQuot<intStart Or intStart<1) And intQuot>0 Then '是注释 ohtml = ohtml & Mid(html,intPos,intQuot-intPos) '找出注释结尾 intPos = InStr(intQuot,html,vbCrLf) ElseIf (intQuot>intStart Or intQuot<1) And intStart>0 Then '跳过字符串的动作 intEnd=InStr(intStart+1,html,"""") Do While intEnd<L If Mid(html,intEnd+1,1)<>"""" Then Exit Do intEnd=InStr(intEnd+2,html,"""") If intEnd<1 Then Err.Raise 7,"ASP语法错误,未结束的字符串" End If Loop '提取ASP代码 ohtml = ohtml & Mid(html,intPos,intStart-intPos+1) If intEnd - intPos > 1 Then '提取字符串 PutString Mid(html,intStart+1,intEnd-intStart-1) ohtml = ohtml & StrRep &"""" '字符串占位 Else '空字符串无需提取 ohtml = ohtml & """" End If intPos = intEnd+1 Else '没有字符串,没有注释 Exit Do End If Loop If intPos>0 Then ohtml = ohtml & Mid(html,intPos) FilterComment = ohtml End Function Private Sub PutString( str) arrStrLength = arrStrLength + 1 ReDim Preserve arrStr(arrStrLength) arrStr(arrStrLength) = str End Sub Private Function getIndex(html, iPos,ByVal i,ByVal j) i = InStr(i + 1, html, strRep) Do Until i<1 Or i>iPos i = InStr(i+1, html, strRep) j = j + 1 If j>arrStrLength Then Exit Do Do While IsEmpty(arrStr(j)) j = j + 1 If j>arrStrLength Then Exit Do Loop Loop getIndex = j End Function '移除类,并尝试在全局执行移除的类 Private Function FilterClass( html) Dim Matches,Match,ClassName,oHtml,LastIndex, ClassStr, iStart Set Matches=REObject("\bClass\s+([\w\d\_]+)\b[\s\S]+?\bEnd\s+Class\b","ig").Execute(html) If Matches.Count>0 Then iStart = 0 LastIndex = 1 For Each Match In Matches oHtml = oHtml & Mid(html,LastIndex,Match.FirstIndex+1-LastIndex) ClassName = Match.SubMatches(0) If Classes.Exists(ClassName)=False Then ClassStr = Match.Value iStart = getIndex(html,Match.FirstIndex,LastIndex-1,iStart) ClassStr = RestoreString(ClassStr, iStart) '直接执行类代码,没有处理类内部的属性,函数等功能的输出,尽量事先处理好 ExecuteGlobal ClassStr Classes.Add ClassName,1 End If LastIndex = Match.FirstIndex+Match.Length+1 Next oHtml = oHtml & Mid(html, LastIndex) FilterClass = oHtml Else FilterClass = html End If End Function '移除Sub,并尝试将Sub转换为Function在全局执行 Private Function FilterSub( html) Dim Matches,Match,SubName,SubStr,oHtml,LastIndex, iStart Set Matches=REObject("\bSub\s+([\w\d\_]+)\b[\s\S]+?\bEnd\s+Sub\b","ig").Execute(html) If Matches.Count>0 Then iStart = 0 LastIndex = 1 For Each Match In Matches oHtml = oHtml & Mid(html,LastIndex,Match.FirstIndex+1-LastIndex) SubName = Match.SubMatches(0) '将Sub替换成Function SubStr = RegReplace("\bSub\b",Match.Value,"Function") SubStr = RegReplace("\b"& FuncStr &"\b",SubStr,SubName) iStart = getIndex(html,Match.FirstIndex,LastIndex-1,iStart) SubStr = RestoreString(SubStr, iStart) ExecuteGlobal SubStr LastIndex = Match.FirstIndex+Match.Length+1 Next oHtml = oHtml & Mid(html, lastIndex) FilterSub = oHtml Else FilterSub = html End If End Function '移除函数,并尝试在全局执行移除的函数 Private Function FilterFunction( html) Dim Matches,Match,FunctionName,FunctionStr,oHtml,LastIndex, iStart Set Matches=REObject("\bFunction\s+([\w\d\_]+)\b[\s\S]+?\bEnd\s+Function\b","ig").Execute(html) If Matches.Count>0 Then iStart = 0 LastIndex = 1 For Each Match In Matches oHtml = oHtml & Mid(html,LastIndex,Match.FirstIndex+1-LastIndex) FunctionName = Match.SubMatches(0) FunctionStr = RegReplace("\b"& FuncStr &"\b",Match.Value,FunctionName) iStart = getIndex(html,Match.FirstIndex,LastIndex-1,iStart) FunctionStr = RestoreString(FunctionStr, iStart) ExecuteGlobal FunctionStr LastIndex = Match.FirstIndex+Match.Length+1 Next oHtml = oHtml & Mid(html, lastIndex) FilterFunction = oHtml Else FilterFunction = html End If End Function End Class
测试文件:
'计算起始时间 Dim StartTime StartTime = Timer '生成对象 Dim C Set C=New xCompile '//这个文件会被预先运行,文件路径写法不重要,比较时是按实际磁盘路径比较的 C.AddInclude "TestFunctions.asp" '//ASP中调用到这个函数的地方会被替换成字符串连接 C.AddOutFun "Echo" C.Param("param")="这是传过去的参数" '//设置是否以全局模式执行 C.GlobalMode = False '//编译文件 C.Compile "Test.asp" C.Clear '//保存编译后的文件到内容 C.SaveTo "index.html" '//输出编译后的内容 Response.Write C '输出执行时间 Response.Write CCur(Timer-StartTime)
相关推荐
ASP.NET Core 2.0 是微软推出的一款开源、跨平台的应用程序框架,适用于构建现代的云原生应用。它支持多种模式,包括MVC、Web API等,同时提供了高性能和可扩展性。在本书中,我们将重点介绍使用MVC模式来构建网站的...
- **项目布局与文件系统**:在创建一个新的ASP.NET Core项目时,会自动生成一系列的文件夹和文件。这些文件夹包括Controllers、Models、Views等,分别用于存放控制器、模型以及视图文件。 - **重要文件**:项目中的...
ASP.NET 采用编译型模型,它将网页代码编译为中间语言(IL),从而提高了执行效率和安全性。与解释型语言不同,编译型语言在运行前已完成全部转换,这使得ASP.NET应用程序运行更快。 2. 支持的语言: ASP.NET支持...
- **非托管代码**:指的是不被CLR管理的代码,例如原生C++代码。 #### 四、构造函数特性 - **构造函数不能继承**:在.NET中,构造函数是不可继承的,这意味着子类不会继承父类的构造函数。 - **构造函数重载与重写...
10. `public`、`simplewind`、`heimao`、`data`:这些可能是项目的静态资源目录、框架或插件代码,或者存储用户生成的数据。`public`通常存放静态文件(如CSS、JS、图片),`simplewind`可能是一个轻量级的PHP框架,...
- **静态文件处理**:掌握如何在 ASP.NET Core 应用程序中处理静态文件,如 CSS 和 JavaScript 文件。 - **路由**:学习 ASP.NET Core 中的路由机制,以便正确地将请求映射到对应的处理程序。 - **URL 重写中间件**...
8. **.NET Native工具链**:这是一个用于编译.NET应用程序为本机代码的工具集,它包括了编译器、链接器和元数据处理工具,使得.NET应用能够实现接近原生性能的运行。 总结起来,.NET Framework 4.6.1是.NET开发的...
1. **类型安全**:通过静态类型系统,TypeScript能够在编译阶段发现潜在的错误,避免了运行时的常见问题,提高了代码质量。 2. **代码提示和智能感知**:在IDE(如Visual Studio Code)中,TypeScript提供自动补全...
6. `.lib` 文件:静态库文件,包含了预编译的代码,可供其他项目使用。 7. `.res` 文件:资源文件,包含了应用程序的图标、字符串、图像等非代码资源。 在开发过程中,开发者可能需要这些文件来集成Developer ...
ExtAspNet是一组专业的Asp.net控件库,拥有原生的AJAX支持和丰富的UI效果, 目标是创建没有JavaScript,没有CSS,没有UpdatePanel,没有WebServices的Web应用程序。 支持的浏览器: IE 7.0+, Firefox 3.0+, Chrome ...
5. **using静态导入**:允许类的静态成员无需前缀类名即可使用,减少了代码冗余,如`using static System.Math;` 后,可以直接调用`Math.PI`。 6. **Expression-bodied成员**:方法、属性、索引器和访问器可以用...
ExtAspNet是一组专业的Asp.net控件库,拥有原生的AJAX支持和丰富的UI效果, 目标是创建没有ViewState,没有JavaScript,没有CSS,没有UpdatePanel,没有WebServices的Web应用程序。 支持的浏览器: IE 7.0+, Firefox...
编译成JavaScript后,TypeScript代码可以在C#和JavaScript交互的项目中使用,提供更好的类型安全性和代码提示。 10. **跨平台框架**,如Electron或Blazor:这些框架允许使用C#和JavaScript混合开发桌面或Web应用。...
5. **继承和多态**:C#支持单一继承,一个类只能从一个基类继承,但可以通过接口实现多继承。多态允许子类重写父类的方法。 6. **异常处理**:使用try-catch-finally语句块处理运行时错误,可以自定义异常类。 7. ...
在JavaScript的世界里,类继承是实现面向对象编程的关键机制之一。然而,JavaScript的原生继承方式,如原型链(prototype chaining)和构造函数传递(constructor function delegation),在处理某些复杂情况时可能...
使用ng build命令编译Angular应用为静态资源,然后在ASP.NET Core中通过静态文件中间件(Static File Middleware)进行托管。这样可以实现前后端分离,提升开发效率和部署灵活性。 【开发与调试】 在开发过程中,...
开发者可以通过定义类来构建复杂的数据结构和行为,通过继承实现代码重用,利用多态实现灵活的设计。 2. **类型系统**: C#有严格的静态类型检查,这意味着在编译期间就能发现大部分类型错误。它支持值类型(如int...
它引入了静态类型系统、类和接口等面向对象特性,以及模块化和装饰器等功能。使用TypeScript可以捕捉类型错误并在编译阶段发现潜在问题,从而提高代码的稳定性和可维护性。在AureliaAspNetTypescript项目中,...
- WebAssembly是低级虚拟机格式,可以被现代浏览器原生支持,用于高效地运行编译后的代码。 - Blazor有两种模式:Blazor Server和Blazor WebAssembly。前者通过 SignalR 与服务器保持连接,后者将整个应用程序和...