數據字典生成工具之旅(6):NVelocity語法介紹及實例


      本章開始將會為大家講解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群

      更多數據字典生成工具資料請點擊數據字典生成工具專題

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM