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

上一篇,本文对ST进表达式元素语法进行详细的了解。

1.简单属性

对于简单属性(区别于集合类型),都是直接调用它的ToString()方法

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

再看一个例子:

	StringTemplate query = new StringTemplate("$title$");
	query.SetAttribute("title", typeof(object));
	Console.WriteLine(query.ToString());
输出:System.Object

2.集合的索引

	string[] strArray = new string[] { "a","b","c","d","e" };
	StringTemplate query = new StringTemplate("$array:{\n当前索引 从1开始计算:$i$,从0开始计算:$i0$ }$");
	query.SetAttribute("array", strArray);
	Console.WriteLine(query.ToString());

输出:

	当前索引 从1开始计算:1,从0开始计算:0
	当前索引 从1开始计算:2,从0开始计算:1
	当前索引 从1开始计算:3,从0开始计算:2
	当前索引 从1开始计算:4,从0开始计算:3
	当前索引 从1开始计算:5,从0开始计算:4

集合不限于Array,可以是实现IList,ICollection,IDictionary等接口的类型。

3.属性引用

如果attribute是一个集合 或 自定义类型,则可以通过attribute.property访问它的属性,自定义类型

	class User {
		public string Name {get;set;}
		public int Age {get;set;}
	}
		
	public static void Main(string[] args)
	{
		User u = new User { Name = "囧月", Age = 1 };
		StringTemplate query = new StringTemplate("姓名:$user.Name$,年龄:$user.Age$");
		query.SetAttribute("user", u);
		Console.WriteLine(query.ToString());
	}
	输出:姓名:囧月,年龄:1

集合类型,可以是Dictionary<T,T>,HashTable等有Key/Value的对象,如:

	Dictionary<string, string> u = new Dictionary<string, string>(1);
	u.Add("Name", "囧月");
	u.Add("Age", "1");
	StringTemplate query = new StringTemplate("姓名:$user.Name$,年龄:$user.Age$");
	query.SetAttribute("user", u);
	Console.WriteLine(query.ToString());

还有一种情况,应该属性ST的自定义集合,没有详细研究:

	StringTemplate st = new StringTemplate("$user:{姓名:$it.Name$,年龄:$it.Age$}$");
	st.SetAttribute("user.{Name,Age}","囧月", 1);
	Console.WriteLine(st.ToString());

当有保留字时:

	Dictionary<string, string> items = new Dictionary<string, string>();
	items.Add("first", "第一");
	items.Add("last", "最后");
	items.Add("1", "数字1");
	StringTemplate st = new StringTemplate("$items.(\"first\")$,$items.(\"last\")$, $items.(\"1\")$");
	st.SetAttribute("items", items);
	Console.WriteLine(st.ToString());
	输出:第一,最后,数字1

其中first、last为保留字,数字1不能直接作为属性名称来引用,与保留字同样处理

下面再看一个错误的例子,当key为int类型时,数字作为保留字处理不能得到预期的结果:

Dictionary<int, int> dict = new Dictionary<int, int>();
			dict.Add(1,11);
			dict.Add(2,22);
			dict.Add(3,33);
			StringTemplate st1 = new StringTemplate("$u.(\"1\")$");
			st1.SetAttribute("u", dict);
			Console.WriteLine(st1.ToString());

这个例子输出为空,应该只能使用集合的方式来得到值

4.多个属性/集合

	string[] strArray = new string[] { "a","b","c","d","e" };
	StringTemplate query = new StringTemplate("$array$");
	query.SetAttribute("array", strArray);
	Console.WriteLine(query.ToString());
	输出:abcde

它等效于:

	string[] strArray = new string[] { "a","b","c"};
	StringTemplate query = new StringTemplate("$array$");
	query.SetAttribute("array", strArray);
	query.SetAttribute("array", "d");
	query.SetAttribute("array", "e");
	Console.WriteLine(query.ToString());

最终都会把array合并成一个集合

	Type[] typeArray = new Type[]{typeof(object),typeof(string),typeof(int),typeof(IList)};
	StringTemplate query = new StringTemplate("$array$");
	query.SetAttribute("array", typeArray);
	Console.WriteLine(query.ToString());
	输出:System.ObjectSystem.StringSystem.Int32System.Collections.IList

通过以上例子可以看出,ST对集合类型,都是先调用每个元素的ToString()方法,再把它们连接起来。

而且默认情况下,是没有分隔符的。接下来看一下分隔符的使用,分隔符两边必须加上双引号:

	string[] strArray = new string[] { "a","b","c","d","e" };
	StringTemplate query = new StringTemplate("$array;separator=\"--\"$");
	query.SetAttribute("array", strArray);
	Console.WriteLine(query.ToString());
	结果:a--b--c--d--e

当集合中有元素为null的时候,这个元素将不会被输出,如果需要输出,则需要指定null条件:

	string[] strArray = new string[] { "a",null,"c",null,"e" };
	StringTemplate query = new StringTemplate("$array;null=\"k\",separator=\"--\"$");
	query.SetAttribute("array", strArray);
	Console.WriteLine(query.ToString());
	结果:a--k--c--k--e  (如果未指定null则为:a--c--e)

5、集合合并

对于多个attribute参数,使用方括号把它们合并成单个集合:

	string[] array1 = new string[] { "a","b","c" };
	string[] array2 = new string[] { "d","e" };
	StringTemplate query = new StringTemplate("$[list1,list2]:{$it$};separator=\",\"$");
	query.SetAttribute("list1", array1);
	query.SetAttribute("list2", array2);
	Console.WriteLine(query.ToString());
	输出结果:a-b-c-d-e

可以看到array1和array2被合并成1个集合,如果模板定义改为$[list1,list2]:{x,y|$x$,$y$};separator=","$则会出现错误。

再看一个例子,不同元素长度:

StringTemplate st1 = new StringTemplate("$[a,b,c]:{$it$};separator=\",\"$");
			st1.SetAttribute("a", "aa");
			st1.SetAttribute("b", new string[]{"b","c","d"});
			st1.SetAttribute("c", typeof(object));
			Console.WriteLine(st1.ToString());
	输出结果:aa,b,c,d,System.Object

再看一个例子,不同类型的合并:

StringTemplate st1 = new StringTemplate("$[a,b,c]:{$if(it.Name)$ $it.Name$ $else$ $it$ $endif$};separator=\",\"$");
			st1.SetAttribute("a", new User{Name="aa"});
			st1.SetAttribute("b", new User[]{new User{Name="b"},new User{Name="c"},new User{Name="d"}});
			st1.SetAttribute("c", typeof(object));
			Console.WriteLine(st1.ToString());
	输出结果: aa , b , c , d , Object

可以看出支持不同类型合并到同一个集合

另外,虽然与$list1,list2:{ x,y | ...}$只差了一对方括号[],但绝对不是一样的。

看起来内容有点多,还是分成2部分吧,省得等下格式乱掉了。

本文地址:http://www.cnblogs.com/lwme/archive/2010/04/29/1724200.html

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

原文地址:https://www.cnblogs.com/lwme/p/1724200.html