本章開始將會為大家講解NVelocity的用法,並帶領大家實現一個簡單的代碼生成器。
NVelocity是一個基於.NET的模板引擎(template engine)。它允許任何人僅僅簡單的使用模板語言(template language)來引用由.NET代碼定義的對象。從而使得界面設計人員與.NET程序開發人員基本分離。
閱讀目錄
NVelocity的常用功能簡介
1、 在頁面中定義變量,並進行簡單的運算。
2、 在頁面中獲得對后台程序實體對象的引用。
3、 在頁面中迭代實體對象集合。
4、 在頁面中獲得實體對象的屬性,及其方法。
5、 對邏輯判斷語句的支持。
基本語法
1、特殊字符介紹
A、“#”:表示開始做什么事情。
B、“$”:表示用於獲得什么。(以$開頭的表示“引用”意思是取得一些東東.可引用變量,屬性,方法)
C、“##“:單行注釋。
D、 “#*… …*#”:多行注釋。
2、關鍵字
A、 Set:開始做什么事情,比如定義變量,給變量重新賦值等。(注意:如果右邊的操作數是一個屬性或命令的引用而返回null,那么賦值將不會成功,且在隨后的VTL中也不能再取出使用,如果要用做if條件,一個解決辦法是,先給變量賦一個值,然后再將一個屬性或命令的引用賦給該變量)
B、 Foreach:迭代語句
C、 If:條件判斷語句
D、 Elseif
E、 Else
F、 Even:雙數執行
G、 Odd :單數執行
K、 Each:每次都執行
(備注:所有變量在未定義之前不能使用(因為我們習慣了有全局變量的習慣),一個合法的VTL標示符是以一個字母開頭的。.NET后台定義的對象除外。模板語言區分大小寫,所有的關鍵字必須為小寫,默認情況下,NVelocity解析是不分大小寫的,當然可以通過設置runtime.strict.math=true,采用嚴格解析模式。)
3.使用示例
1、 在頁面中使用變量
定義變量:#set($a = “CNF”)
引用變量:歡迎光臨:$a
定義變量:#set($a = 1)
運算:#set($a = $a + 1)
輸出:$a ##得:2
運算:#set($a = $a*5)
輸出:$a ##得:10
#set( $criteria = ["name", "address"] )
#foreach( $criterion in $criteria )
#set( $result = false ) //先設置默認值
#set( $result = $query.criteria($criterion) )
#if( $result )
Query was successful
#end
#end
(備注:從以上可以看出nVelocity的替換順序與.NET程序代碼的執行基本一致,如果放在Foreach語句塊中可以實現累加。並用If語句獲得行號,對特殊行號的內容特殊處理。所有變量在未定義之前不能使用,.NET后台對象除外,最好采用正規引用格式,${a},正規引用格式一般用於在模板中直接調整字符串內容;靜態引用輸出:NVelocity遇到一個不能處理的引用時,一般他會直接輸出這個引用$email的寫法,頁面上會看到的是$email,我們可以在$后面加上一個!號,那么就會輸出空白.$!{email}如果不能處理會輸出空白。如果email己定義了 (比如它的值是 foo),而這里你卻想輸出 $email. 這樣一個字符串,就需要使用轉義字符”\”,如:\$email)
2、 在頁面中使用條件判斷語句
#if ($p.StrSex == "女")
#set($Sex = "女士")
#elseif ($p.StrSex == "男")
#set($Sex = "先生")
#elseif ($p.StrSex == "無")
#set($Sex = "人妖")
#else
#set($Sex = "怪物")
#end
(備注:可以嵌套在Foreach語句塊中,用於對每個列表對象進行特殊顯示處理。)
4、使用對象方法
定義變量:#set($str = “CNF”)
調用方法:$str.SubString(0,1)
輸出:C
定義變量:#set($a = 123)
調用方法:$a.GetType()
輸出:System.Int32
(備注:不管是.NET代碼定義的對象,還是設計人員在頁面中定義的變量,都可以使用對象的方法及屬性,這一點非常強大。)
5、使用even與odd簡化代碼,each輔助
如上面所說用IF語句可以在列表中為每行創建不同的樣式,但如果只需要區分單行與雙行的話,可以使用even與odd簡化代碼。如下:
#foreach($p in $ps)
#even
<p>雙行:$p.StrName</p>
#odd
<p>單行:$p.StrName</p>
#end
(備注:在使用這兩個關鍵字時,出現了與創建宏一樣的問題,即在初始化模板引引擎的時候,如果是用模板文件內容初始化的,會出現問題)
實例介紹
1.生成前台html
怎么通過NVelocity生成上圖的表格呢,請看下面的例子,先看模版文件
<table id="appMenu" style="background-color: rgb(114, 136, 172); border: solid 1px #00377a; height: 23px; color: White; font-size: 12px; font-family: 宋體; width: 100%; cursor: default;" cellspacing="0" cellpadding="0"> <tr> <td style="padding-left: 5px" nowrap=""> <b>學生信息列表</b> </td> <td style="padding-right: 5px; text-align: right;" nowrap=""> <span><span onclick="alert(1)">新增</span> <span class="mnuBtn" onclick="alert(2)">刪除</span> </span> </td> </tr> </table> <table border="1" style="width: 100%; border: solid 1px #dbdac9; border-collapse: collapse; table-layout: fixed; cursor: default; font-size: 12px; font-family: 宋體;" cellspacing="0" cellpadding="0"> <colgroup> <col width="40"> <col width="12%"> <col width="12%"> <col width="12%"> <col width="12%"> <col width="12%"> <col width="12%"> <col width="12%"> <col /> </colgroup> <tr height="22" style="background-color: rgb(233, 231, 215);"> <th align="center"> 序號 </th> <th> 學生姓名 </th> <th> 年級 </th> <th> 專業 </th> <th> 性別 </th> <th> 考試成績 </th> <th> 級別 </th> <th> 申請時間 </th> <th> 申請狀態 </th> </tr> #foreach( $s in $ListStudent ) <tr height="22"> <td> $s.Num </td> <td> $s.Name </td> <td> $s.Grade </td> <td> $s.Major </td> <td> $s.Sex </td> <td align="right"> #if($s.Status=="已審核") $s.Score #else <input style="border:solid 1px black;width:95%;" value="$s.Score" /> #end </td> <td align="right"> #if($s.Status=="已審核") $s.Level #else <input style="border:solid 1px black;width:95%;" value="$s.Level" /> #end </td> <td align="center"> $s.GetAppoveDate($s.Status) </td> <td align="center"> $s.Status </td> </tr> #end </table>
用到了foreach循環和調用類的方法,這里特別強調一下,其實NVelocity和直接寫后台代碼類似,通過.方法名就可以調用變量有的方法
后台代碼文件
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { Hashtable ht = new Hashtable(); List<Student> list = new List<Student>(); for (int i = 1; i < 10; i++) { Student s = new Student(); s.Num = i; s.Name = "Test"+i.ToString(); s.Score = i.ToString(); s.Status = i % 2 == 0 ? "未審核" : "已審核"; s.Sex = i % 2 == 0 ? "男" : "女"; s.Level = i.ToString (); s.Major = "測試"; s.Grade = "大一"; list.Add(s); } ht["ListStudent"] = list; divTemplate.InnerHtml = FileGen.GetFileText(Server.MapPath(@"模版文件\列表模版.vm"), ht).ToString(); } }
為了更方面的使用NVelocity,封裝了一個幫助類即上面的FileGen類
using System; using System.Collections.Generic; using System.Linq; using System.Text; using NVelocity.App; using Commons.Collections; using NVelocity.Runtime; using NVelocity; using NVelocity.Context; using System.IO; using System.Collections; namespace NVelocityDemo { /// <summary> /// SQL文件生成 /// </summary> public class FileGen { /// <summary> /// 通過模版文件路徑讀取文件內容 /// </summary> /// <param name="path">模版文件路徑</param> /// <param name="ht">模版文件的參數</param> /// <returns>StringWriter對象</returns> public static StringWriter GetFileText(string path, Hashtable ht) { if (String.IsNullOrEmpty(path)) { throw new ArgumentNullException("模版文件路徑為空!"); } try { string tmpPath = path.Substring(0,path.LastIndexOf(@"\")); string filePath = path.Substring(path.LastIndexOf(@"\")+1); //創建NVelocity引擎的實例對象 VelocityEngine velocity = new VelocityEngine(); ExtendedProperties props = new ExtendedProperties(); props.AddProperty(RuntimeConstants.RESOURCE_LOADER, "file"); props.AddProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, tmpPath); props.AddProperty(RuntimeConstants.FILE_RESOURCE_LOADER_CACHE, true); props.AddProperty(RuntimeConstants.INPUT_ENCODING, "utf-8"); props.AddProperty(RuntimeConstants.OUTPUT_ENCODING, "utf-8"); velocity.Init(props); //從文件中讀取模板 Template temp = velocity.GetTemplate(filePath); IContext context = new VelocityContext(); foreach (string key in ht.Keys) { context.Put(key, ht[key]); } //合並模板 StringWriter writer = new StringWriter(); temp.Merge(context, writer); return writer; } catch (Exception ex) { throw ex; } } /// <summary> /// 通過模版文件路徑讀取文件內容 /// </summary> /// <param name="path">模版文件路徑</param> /// <param name="ht">模版文件的參數</param> /// <param name="strOutputPath">生成文件的輸出路徑,如c:\1.txt</param> /// <returns>TextWriter對象</returns> public static void GetFile(string path, Hashtable ht,string strOutputPath) { if (String.IsNullOrEmpty(strOutputPath)) { throw new ArgumentNullException("模版文件輸出路徑為空!"); } try { StringWriter stringW=GetFileText(path, ht); StreamWriter sw = new StreamWriter(strOutputPath,false,Encoding.UTF8); sw.Write(stringW.ToString()); sw.Close(); } catch (Exception ex) { throw ex; } } } }
上面的例子差不多將NVelocity語法都使用到了,沒使用過NVelocity的可以通過上述例子學習語法,下一章將利用本章的語法寫出一個簡單的代碼生成器,敬請期待!
工具源代碼下載
目前總共有經過了七個版本的升級,現在提供最新版本的下載地址
數據字典生成工具V2.0安裝程序 | 最新安裝程序 | |
數據字典生成工具源代碼 | 最新源代碼 | |
http://code.taobao.org/svn/DataDicPub | SVN最新源碼共享地址 |
學習使用
如果你使用了該工具,或者想學習該工具,歡迎加入這個小組,一起討論數據字典生成工具、把該工具做的更強,更方便使用,一起加入147425783 QQ群。
更多數據字典生成工具資料請點擊數據字典生成工具專題。