StringTemplate.Net 学习笔记(4):表达式元素语法(下)

来源:互联网 发布:飞利浦空气净化器 知乎 编辑:程序博客网 时间:2024/06/08 04:02

6.匿名模板/遍历

匿名模板的语法为:$attribute:{anonymous-template}$,遍历attribute,对每个元素都应用此匿名模板,自动设置it为当前元素名称:

string[] strArray = new string[] { "a","b","c" };StringTemplate st = new StringTemplate("$array:{当前元素$it$};separator=/",/"$");st.SetAttribute("array", strArray);Console.WriteLine(st.ToString());
输出结果:当前元素a,当前元素b,当前元素c

假如不想使用it作为当前元素名称,可以手动设置:

string[] strArray = new string[] { "a","b","c" };StringTemplate st = new StringTemplate("$array:{current|当前元素$current$};separator=/",/"$");st.SetAttribute("array", strArray);Console.WriteLine(st.ToString());

以上都是对attribute应用单个匿名模板,多个匿名模板的使用方法与单个一样,只不过是模板个数的差别。

顺序(从左到右)应用多个模板,对每个attribute的元素都应用多个模板。
语法:$attribute:{anonymous-template1}:{anonymous-template2}...:{anonymous-templateN}$ ,示例:

string[] strArray = new string[] { "a","b","c" };StringTemplate st = new StringTemplate("$array:{当前元素$it$}:{current|'$current$'}:{[$it$]}$");st.SetAttribute("array", strArray);Console.WriteLine(st.ToString());
输出结果:['当前元素a']['当前元素b']['当前元素c']

交替应用多个模板,与顺序应用不同的是,每个attribute的元素只应用一个模板。
语法:$attribute:{anonymous-template1},{anonymous-template2}...,{anonymous-templateN}$,示例 :

string[] strArray = new string[] { "a","b","c" };StringTemplate st = new StringTemplate("$array:{current|当前元素$current$},{样式2$it$},{样式3$it$};separator=/",/"$");st.SetAttribute("array", strArray);Console.WriteLine(st.ToString());
输出结果:当前元素a,样式2b,样式3c

还可以同时应用交替模板与顺序模板,每隔一个冒号":"为一组:

string[] strArray = new string[] { "a","b","c" };StringTemplate st = new StringTemplate("$array:{样1式$it$},{样2式$it$}:{'$it$'},{|$it$|}:{[$it$]},{<$it$>},{($it$)}$");st.SetAttribute("array", strArray);Console.WriteLine(st.ToString());
输出:['样1式a']<|样2式b|>('样1式c')

以上都是遍历单个集合参数,可以使用多个参数

string[] array1 = new string[] { "a","b","c" };string[] array2 = new string[] { "d","e" };StringTemplate st = new StringTemplate("$array1, array2:{a1,a2|$a1$,$a2$};separator=/"-/"$");st.SetAttribute("array1", array1);st.SetAttribute("array2", array2);Console.WriteLine(st.ToString());
输出结果:a,d-b,e-c,

当使用多个集合参数时,如果集合元素个数不一致,则以元素个数最多的那个集合为准。

另外要注意,多个参数不能应用多个模板(也可能是我没找到方法)。

话说自动设置的当前元素名称除了it外,还设置了attr,这个是从riccc翻译的http://www.cnblogs.com/RicCC/archive/2007/06/03/Enforcing-Strict-Model-View-Separation-in-Template-Engines.html看到的,it和attr可以同时使用,不过手动设置了当前元素名称以后,it和attr都会失效。

7.模板文件

为了方便演示,将使用到的模板文件都放到bin/debug目录下(当前运行在debug模式下)

先新建一个模板文件,名称为template1.st,内容为:

$title$

调用:

StringTemplate query = new StringTemplate("$template1()$");query.SetAttribute("title", "StringTemplate学习");Console.WriteLine(query.ToString());
输出:StringTemplate学习

还可以直接传递值:

StringTemplate query = new StringTemplate("$template1(title=/"StringTemplate学习/")$");Console.WriteLine(query.ToString());

或者通过另外定义的变量传递:

StringTemplate query = new StringTemplate("$template1(title=mtitle)$");query.SetAttribute("mtitle", "StringTemplate学习");Console.WriteLine(query.ToString());

如果被调用的模板文件名为保留字,如:first,则相应调用代码为$("first")()$

新建一个模板,名称为anonymous1.st,内容:

$it$

使用匿名模板作为参数传递:

StringTemplate st = new StringTemplate("$anonymous1(it={$name1$ $name2$})$");st.SetAttribute("name1", "囧");st.SetAttribute("name2", "月");Console.WriteLine(st.ToString());
输出:囧 月

新建一个模板format1.st,内容:

‘囧月’

新建一个模板format2.st,内容:

[$item$]

把模板作为参数传递:

StringTemplate st = new StringTemplate("$format2(item=format1())$");Console.WriteLine(st.ToString());
输出:[‘囧月’]

模板应用到attribute

新建一个模板,名称为user1.st,内容:

姓名:$it.Name$,年龄:$it.Age$

声明一个User类型

class User {public string Name {get;set;}public int Age {get;set;}}

单个对象:

User u =new User { Name = "囧月", Age = 1 };StringTemplate st = new StringTemplate("$users:user1()$");st.SetAttribute("users", u);Console.WriteLine(st.ToString());
输出:姓名:囧月,年龄:1

集合:

User[] u = new User[]{new User { Name = "囧月", Age = 1 },new User { Name = "小强", Age = 2 },new User { Name = "小红", Age = 3 }};StringTemplate st = new StringTemplate("$users:user1();separator=/"|/"$");st.SetAttribute("users", u);Console.WriteLine(st.ToString());
输出:姓名:囧月,年龄:1|姓名:小强,年龄:2|姓名:小红,年龄:3

新建一个模板文件user2.st,内容:

$title$ 姓名:$it.Name$,年龄:$it.Age$

传递参数:

User u = new User { Name = "囧月", Age = 1 };StringTemplate st = new StringTemplate("$users:user2(title=mtitle)$");st.SetAttribute("users", u);st.SetAttribute("mtitle", "StringTemplate学习");Console.WriteLine(st.ToString());
输出:StringTemplate学习 姓名:囧月,年龄:1

不再一一演示,其他使用方式与匿名模板一样,区别在于:

  1. 模板内容外置
  2. 模板调用部分的{anonymous-template}符号换成模板文件名:template()

8.其他

string[] strArray = new string[] { "a","b","c","d",null,"e" };StringTemplate st = new StringTemplate("第一个:$first(array)$ 最后一个:$last(array)$ 换行:$//n$ 排除第一个$rest(array)$ 制表符$//t$ 排除最后一个$trunc(array)$ 回车:$//r$ 忽略空元素:$strip(array)$ 输出当前的默认表达式分隔符//$ 长度:$length(array)$ unicode字符:$//u56E7$ 忽略空元素之后的长度:$length(strip(array))$ $! 注释注释注释注释 !$");st.SetAttribute("array", strArray);Console.WriteLine(st.ToString());
    输出:
第一个:a 最后一个:e 换行: 排除第一个bcde 制表符   排除最后一个abcd 回车: 忽略空元素:abcde 输出当前的默认表达式分隔符$ 长度:6 unicode字符:囧 忽略空元素之后的长度:5

最后,来一个简单且完整点的例子,作为表达式元素语法部分的总结吧~

新建文件user0.st,内容:

$! 显示用户列表 !$$/t$/$用户列表 -- $/u56E7/u6708$/$:$users:user1(),user2(),user3()$$/n$记录总数:$length(users)$

新建文件user1.st,内容

$/n$[序号:$i$,姓名:$it.Name$,年龄:$it.Age$]

新建文件user2.st,内容

$/n${序号:$i$,姓名:$it.Name$,年龄:$it.Age$}

新建文件user3.st,内容

$/n$'序号:$i$,姓名:$it.Name$,年龄:$it.Age$'

代码:

class User {public string Name {get;set;}public int Age {get;set;}}public static void Main(string[] args){User[] u = new User[]{new User { Name = "囧月", Age = 1 },new User { Name = "小强", Age = 2 },null,new User { Name = "小红", Age = 3 },new User { Name = "小黑", Age = 3 },new User { Name = "小白", Age = 3 },new User { Name = "小蓝", Age = 3 },new User { Name = "小绿", Age = 3 }};StringTemplateGroup stg = new StringTemplateGroup("stgroup", Environment.CurrentDirectory);StringTemplate st = stg.GetInstanceOf("user0");st.SetAttribute("users", u);Console.WriteLine(st.ToString());Console.ReadKey(true);}

输出:

        $用户列表 -- 囧月$:[序号:1,姓名:囧月,年龄:1]{序号:2,姓名:小强,年龄:2}'序号:3,姓名:小红,年龄:3'[序号:4,姓名:小黑,年龄:3]{序号:5,姓名:小白,年龄:3}'序号:6,姓名:小蓝,年龄:3'[序号:7,姓名:小绿,年龄:3]记录总数:8

弄的我晕晕乎乎,但愿没有遗漏~

困死了,准备睡觉了

参考:http://www.antlr.org/wiki/display/ST/Expressions

原创粉丝点击