数据字典生成工具之旅(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最新源码共享地址

回到顶部

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏c#开发者

利用JDBC对数据库的增删查改

   在本节中,我们将通过一个示例说明如何利用JDBC对数据库进行增删查改等各种操作,以及怎样对结果集中的数据进行处理。     我们假设现在数据库中有一张...

3257
来自专栏潇涧技术专栏

Lint Tool Analysis (1)

本系列的几篇源码分析文档意义不大,如果你正好也在研究lint源码,或者你想知道前面自定义lint规则中提出的那几个问题,抑或你只是想大致了解下lint的源码都有...

411
来自专栏菩提树下的杨过

Silverlight:获取ContentTemplate中的命名控件

项目开发中遇到一个要求,需要将ComboBox右侧中的小三角箭头给去掉,通过Blend工具“编辑ComboBox的模板副本”得知,这是一个名为"BtnArrow...

1878
来自专栏BaronTalk

RxJava系列番外篇:一个RxJava解决复杂业务逻辑的案例

之前写过一系列RxJava1的文章,也承诺过会尽快有RxJava2的介绍。无奈实际项目中还未真正的使用RxJava2,不敢妄动笔墨。所以这次还是给大家分享一个使...

3368
来自专栏大大的微笑

java使用mina和websocket通信

这里以mina整合springMVC为例: //springMVC的配置: <!-- mina --> <bean class="org.spring...

1K10
来自专栏Java Edge

Redis数据类型StringListsSetsHashes

Redis中最基本的类型。 Redis中的String 类型是二进制安全的,也就是说在Redis中String类型可以包含各种数据,比如一张JPEG图片或者是...

862
来自专栏一个会写诗的程序员的博客

Spring Boot 使用 Kotlin Script Template 模板引擎kts 开发web

在 Spring Framework 5.0 M4 中引入了一个专门的Kotlin支持。

832
来自专栏Seebug漏洞平台

从WordPress SQLi谈PHP格式化字符串问题

近日,WordPress爆出了一个SQLi漏洞,漏洞发生在WP的后台上传图片的位置,通过修改图片在数据库中的参数,以及利用php的sprintf函数的特性,在删...

38811
来自专栏Java Web

Java Web -【分页功能】详解

分页简介 分页功能在网页中是非常常见的一个功能,其作用也就是将数据分割成多个页面来进行显示。 使用场景: 当取到的数据量达到一定的时候,就需要使用分页来进...

3493
来自专栏Java成神之路

Eclipse插件开发_学习_02_GEF入门实例

(2)搜索 editors,选择 org.eclipse.ui.editors  扩展点,finish

972

扫码关注云+社区