您的位置:首页 > 其它

StringTemplate详谈

2012-03-01 10:05 537 查看
stringTemplate是一个模板引擎,同时支持java,C#,Python.

StringTemplate 语法说明

StringTemplate的语法是以$xxxx$来进行分割的. stringtemplate关键写是区分大小写的.powered by 25175.net

属性引用

名称属性

在模板中,这个是最常用的一个属性.用于显示文字.如下:

你的邮件地址:$email$

替换属性名为email的值.

同一个属性可以有多个值,多个值的语法如下

$value;null="xxx",separator=", "$

定义value属性,当value为null则显示xxx.如果有多个属性值则以,号分开

字段引用

如果一个属性名称是对象或集合.可以用 属性名称.字段名 访问字段值

例如:

你的姓名: $人.姓名$

你的邮件:$人.邮件$

使用语法: $对象名.字段名$

在C#可以直接将一个对象设置到一个属性名称中.

如:

User us = new User();

us.Name = "xxsssx";

us.Value ="80";

StringTemplate st = new StringTemplate("$User.Name$,$User.Value$");

st.SetAttribute("User", us);

Console.WriteLine(st.ToString());

对于键/值对象,也同样使用上面方式进行访问如:

StringTemplate a = new StringTemplate("$user.name$, $user.phone$");

Hashtable user = new Hashtable();

user.Add("name", "Terence");

user.Add("phone", "none-of-your-business");

a.SetAttribute("user", user);

string results = a.ToString();

自定义属性字段名

格式: $属性名:{it.字段名}$

例如:

StringTemplate st = new StringTemplate("$abcdef:{第一个: $it.ddddd$ 第二个:$it.ddddd$}$");

st.SetAttribute("abcdef.{ddddd,ddddd}","中国人", "我不来了");

Console.WriteLine(st.ToString());

如果字段名是保留字,可以使用$对象名.("保留字")$

一次显示多个属性

$[属性名,属性名]$

模板引用

必需把模板加入同一个模板组,才能相互之间调用模板.

通过$模板名()$来调用模板

模板传参数

$模板名(参数名=参数值,参数名=参数值)$

例如:

StringTemplateGroup Group = new StringTemplateGroup("Temp");

Group.Definetemplate("link",
"<a href='$url$'>$title$</a>");

StringTemplate st = new StringTemplate(Group, "调用link模板,显示链接 $link(url=\"/faq/view?ID=\"+faqid, title=faqtitle)$ ,真的啊!");

st.SetAttribute("faqid", 1);

st.SetAttribute("title","中华人民共和国");

Console.WriteLine(st.ToString());

循环显示使用

User us = new User();

us.Name = "哈哈";

us.Value = "99";

List<User> uss = new List<User>();

uss.Add(us);

uss.Add(us);

uss.Add(us);

uss.Add(us);

StringTemplate st = new StringTemplate("<table>$User:{<tr>$it.Name$<td></td>$it.Value$</tr>}$</table>");

st.SetAttribute("User", uss);

Console.WriteLine(st.ToString());

通过模板交替显示

StringTemplateGroup group = new StringTemplateGroup("Test");

group.Definetemplate("TrRed",
"<tr class=red><td>$it.name$</td><td>$it.value$</td></tr>\n");

group.Definetemplate("TrWither",
"<tr class=wither><td>$it.name$</td><td>$it.value$</td></tr>\n");

StringTemplate st = new StringTemplate(group, "<table>$User:TrRed(),TrWither()$</table>");

User us = new User();

us.Name = "哈哈哈";

us.Value = "999";

List<User> uss = new List<User>();

uss.Add(us);

uss.Add(us);

uss.Add(us);

st.SetAttribute("User", uss);

Console.WriteLine(st.ToString());

例子教程下载:下载

附:英文语法介绍
Syntax
Description
<attribute>
Evaluates to the value of attribute.ToString() if
it exists else empty string.
<i>,
<i0>
The iteration number indexed from one and from zero, respectively, when referenced within a template
being applied to an attribute or attributes.
<attribute.property>
Looks for property of attribute as
a property (C#), then accessor methods like getProperty()or isProperty().
If that fails, StringTemplate looks
for a raw field of the attribute calledproperty.
Evaluates to the empty string if no such property is found.
<attribute.(expr)>
Indirect property lookup. Same as attribute.property except
use the value of expr as
the property_ name. Evaluates to the empty string if no such property is found.
<multi-valued-attribute>
Concatenation of ToString() invoked
on each element. If multi-valued-attribute is
missing his evaluates to the empty string.
<multi-valued-attribute;
separator=expr>
Concatenation of ToString() invoked
on each element separated by expr.
<template(argument-list)>
Include template.
The argument-list is
a list of attribute assignments where each assignment is of the form arg-of-template=expr where expr is
evaluated in the context of the surrounding template

not of the invoked template.
<(expr)(argument-list)>
Include template whose
name is computed via expr.
The argument-list is
a list of attribute assignments where each assignment is of the form attribute=expr.
Example $(whichFormat)()$ looks
up whichFormat's value
and uses that as template name. Can also apply an indirect template to an attribute.
<attribute:template(argument-list)>
Apply template to attribute.
The optional argument-list is
evaluated before application so that you can set attributes referenced within template.
The default attribute it is
set to the value of attribute.
If attribute is
multi-valued, then it is
set to each element in turn and template is
invoked n times
where n is
the number of values in attribute.
Example: $name:bold() appliesbold() to name's
value.
<attribute:(expr)(argument-list)>
Apply a template, whose name is computed from expr,
to each value of attribute.
Example$data:(name)()$ looks
up name's
value and uses that as template name to apply to data.
<attribute:t1(argument-list):
... :tN(argument-list)>
Apply multiple templates in order from left to right. The result of a template application upon a multi-valued
attribute is another multi-valued attribute. The overall expression evaluates to the concatenation of all elements of the final multi-valued attribute resulting from templateN'sapplication.
<attribute:{anonymous-template}>
Apply an anonymous template to each element of attribute.
The iterated it atribute is
set automatically.
<attribute:{argument-name_
| _anonymous-template}>
Apply an anonymous template to each element of attribute.
Set the argument-name to
the iterated value and also set it.
<a1,a2,...,aN:{argument-list_
| _anonymous-template}>
Parallel list iteration. March through the values of the attributes a1..aN,
setting the values to the arguments in argument-list in
the same order. Apply the anonymous template. There is no defined it value
unless inherited from an enclosing scope.
<attribute:t1(),t2(),...,tN()>
Apply an alternating list of templates to the elements of attribute.
The template names may include argument lists.
<if(attribute)>subtemplate

<else>subtemplate2

<endif>
If attribute has
a value or is a bool object
that evaluates to true,
include subtemplate else
include subtemplate2.
These conditionals may be nested.
<if(!attribute)>subtemplate<endif>
If attribute has
no value or is a bool object
that evaluates to false,
include subtemplate.
These conditionals may be nested.
<first(attr)>
The first or only element of attr.
You can combine operations to say things likefirst(rest(names)) to get second element.
<last(attr)>
The last or only element of attr.
<rest(attr)>
All but the first element of attr.
Returns nothing if $attr$ a single valued.
<strip(attr)>
Returns an iterator that
skips any null values in $attr$. strip

=x when x is a single-valued attribute.
<length(attr)>
Return an integer indicating how many elements in length $attr$
is. Single valued attributes return 1. Strings are not special; i.e., length("foo")
is 1 meaning "1 attribute". Nulls are counted in lists so a list of 300 nulls is length 300. If you don't want to count nulls, uselength(strip(list)).
\$ or \<
escaped delimiter
prevents $ or < from
starting an attribute expression and results in that single character.
<\ >, <\n>, <\t>, <\r>
special characters:
space, newline, tab, carriage return.
<! comment
!>, $! comment
!$
1 变量替换

public static void fun1() {

StringTemplate st = new StringTemplate(

"对象变量替换 姓名:$KeyList.Name$, 年龄:$KeyList.Age$ ");

HashMap ht = new HashMap();

ht.put("Name", "李四");

ht.put("Age", "35");

st.setAttribute("KeyList", ht);

System.out.print(st.toString());

}

2 自定义集合替换

public static void fun2() {

StringTemplate st = new StringTemplate(

"自定义集合替换 $List:{姓名:$it.Name$ 年龄:$it.Age$}$");

st.setAttribute("List.{Name,Age}", "王二", "29");

System.out.print(st.toString());

}

3 对象变量替换

定义类

private static class User {

String name;

String age;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getAge() {

return age;

}

public void setAge(String age) {

this.age = age;

}

}

public static void fun3() {

User us = new User();

us.name = "张三";

us.age = "23";

List<User> uss = new ArrayList<User>();

uss.add(us);

uss.add(us);

uss.add(us);

uss.add(us);

uss.add(us);

StringTemplate st = new StringTemplate(

"<table>$Item:{<tr class=black><td>$it.name$</td></tr>},{<tr class=red><td>$it.age$</td></tr>};separator=\"\n\"$</table>");

st.setAttribute("Item", uss);

System.out.print(st.toString());

}

交叉替换

public static void fun4() {

User us = new User();

us.name = "张三";

us.age = "23";

List<User> uss = new ArrayList<User>();

uss.add(us);

uss.add(us);

uss.add(us);

uss.add(us);

uss.add(us);

StringTemplateGroup sg = new StringTemplateGroup("GroupTest");

sg.definetemplate("RowRed",

"<tr class=red><td>$it.Name$</td><td>$it.Age$</td></tr>\n");

sg.definetemplate("Rowblack",

"<tr class=black><td>$it.Name$</td><td>$it.Age$</td></tr>\n");

StringTemplate st = sg.definetemplate("List",

"<table>$Item:RowRed(),Rowblack()$</table>");

st.setAttribute("Item", uss);

System.out.print(st.toString());

}

4 条件判断

public static void fun5() {

StringTemplate st = new StringTemplate(

"当前用户登陆状态: $if(IsAdmin)$ 用户登陆成功! $else$ 用户没有登陆! $endif$");

st.setAttribute("IsAdmin", true);

System.out.print(st.toString());

}

5 sql语句实现

theQuery.st内容

SELECT $column; separator=","$ FROM $table$;

public static void fun6() {

// 一个sql语句的实现

StringTemplateGroup group = new StringTemplateGroup("myGroup", "c:/");

StringTemplate query = group.getInstanceOf("theQuery");

query.setAttribute("column", "name");

query.setAttribute("column", "email");

query.setAttribute("table", "User");

System.out.print(query.toString());

}

6 使用AttributeRenderer

private static class DateRenderer implements AttributeRenderer {

public String toString(Object o) {

SimpleDateFormat f = new SimpleDateFormat("yyyy.MM.dd");

return f.format(((Calendar) o).getTime());

}

}

public static void fun7() {

StringTemplate st = new StringTemplate("date: <created>",

AngleBracketTemplateLexer.class);

st.setAttribute("created", new GregorianCalendar(2005, 07 - 1, 05));

st.registerRenderer(GregorianCalendar.class, new DateRenderer());

String result = st.toString();

System.out.print(result.toString());

}

==========================

示例2

==========================

using System;

using System.Collections.Generic;

using System.Text;

using Antlr.StringTemplate;

using Antlr.StringTemplate.Language;

using System.IO;

using System.Collections;

using System.Collections.Specialized;

namespace TemplateExplame

{

class Program

{

static void Main(string[] args)

{

//简单变量替换();

//复杂变量替换();

//对象变量替换();

//键值类型替换();

//自定义集合替换();

//同时显示多个变量();

//模板调用();

//给调用模板传参数();

//值模板();

//简单循环();

//交差循环显示();

//通过模板交差循环();

//条件判断();

//从文件中创建模板();

}

#region "变量处理"

private static void 简单变量替换()

{

StringTemplate st = new StringTemplate("简单变量替换 $Text$,真的啊!");

st.SetAttribute("Text", "中华人民共和国");

Console.WriteLine(st.ToString());

}

private static void 复杂变量替换()

{

StringTemplate st = new StringTemplate("复杂变量替换 $Text;null=\"为空值\",separator=\",\"$ 真是复杂啊!");

st.SetAttribute("Text", "中国",null,"台湾","印度");

Console.WriteLine(st.ToString());

}

/// <summary>

/// 如果对象的字段名中有保留字,请用对象名.("变量名")来进行访问.

/// </summary>

private static void 对象变量替换()

{

StringTemplate st = new StringTemplate("对象变量替换 姓名:$User.Name$, 年龄:$User.Age$ ");

User us = new User();

us.Name = "张三";

us.Age = "30";

st.SetAttribute("User", us);

Console.WriteLine(st.ToString());

}

private static void 键值类型替换()

{

StringTemplate st = new StringTemplate("对象变量替换 姓名:$KeyList.Name$, 年龄:$KeyList.Age$ ");

Hashtable ht = new Hashtable();

ht.Add("Name", "李四");

ht.Add("Age", "35");

st.SetAttribute("KeyList", ht);

Console.WriteLine(st.ToString());

}

private static void 自定义集合替换()

{

StringTemplate st = new StringTemplate("自定义集合替换 $List:{姓名:$it.Name$ 年龄:$it.Age$}$");

st.SetAttribute("List.{Name,Age}", "王二", "29");

Console.WriteLine(st.ToString());

}

private static void 同时显示多个变量()

{

StringTemplate st = new StringTemplate("变量相加 $[Temp1,Temp2,Temp3]$");

//StringTemplate st = new StringTemplate("变量相加 $[Temp1,Temp2,Temp3];separator=\",\"$");

st.SetAttribute("Temp1", "变量1");

st.SetAttribute("Temp2", "变量2");

st.SetAttribute("Temp3", "变量3");

Console.WriteLine(st.ToString());

}

#endregion

#region "模板应用"

/// <summary>

/// 模板要相互调用,必需将要调用的模板放入同一个模板组里,才能相互调用.

/// </summary>

private static void 模板调用()

{

StringTemplateGroup sg = new StringTemplateGroup("GroupTest");

sg.Definetemplate("Box",
"中华人民共和国中华人民共和国,中华人民共和国");

StringTemplate st = sg.Definetemplate("List",
"下面是我调用Box模板内容:\n$Box()$");

Console.WriteLine(st.ToString());

}

/// <summary>

/// 参数可以为值,变量,模板

/// </summary>

private static void 给调用模板传参数()

{

StringTemplateGroup sg = new StringTemplateGroup("GroupTest");

sg.Definetemplate("BoxA",
"我不来了()");

sg.Definetemplate("Box",
"中华人民共和国,中华全国 Title: $Title$ !!");

StringTemplate st = sg.Definetemplate("List",
"下面是我调用Box模板内容:\n$Box(Title=\"标题值\")$"); //传变量值

//StringTemplate st = sg.Definetemplate("List",
"下面是我调用Box模板内容:\n$Box(Title={$Titles$})$"); //传变量

//StringTemplate st = sg.Definetemplate("List",
"下面是我调用Box模板内容:\n$Box(Title=BoxA())$"); //传模板

st.SetAttribute("Titles", "标题参数值");

Console.WriteLine(st.ToString());

}

private static void 值模板()

{

StringTemplateGroup sg = new StringTemplateGroup("GroupTest");

sg.Definetemplate("Box",
"中华人民共和国,,,,");

StringTemplate st = new StringTemplate(sg, "调用值模板$Mys:Box();separator=\"==\"$------s");

st.SetAttribute("Mys", "中国");

st.SetAttribute("Mys", "中国");

Console.WriteLine(st.ToString());

}

#endregion

#region "循环显示"

private static void 简单循环()

{

StringTemplate st = new StringTemplate("<table>$Item:{<tr><td>$it$要循环显示的内容</td></tr>}$</table>");

for (int i = 0; i < 10; i++)

{

st.SetAttribute("Item", i);

}

Console.WriteLine(st.ToString());

}

private static void 交差循环显示()

{

User us = new User();

us.Name = "张三";

us.Age = "23";

List<User> uss = new List<User>();

uss.Add(us);

uss.Add(us);

uss.Add(us);

uss.Add(us);

uss.Add(us);

StringTemplate st = new StringTemplate("<table>$Item:{<tr class=black><td>$it.Name$</td></tr>},{<tr class=red><td>$it.Age$</td></tr>};separator=\"\n\"$</table>");

st.SetAttribute("Item", uss);

Console.WriteLine(st.ToString());

}

private static void 通过模板交差循环()

{

User us = new User();

us.Name = "张三";

us.Age = "23";

List<User> uss = new List<User>();

uss.Add(us);

uss.Add(us);

uss.Add(us);

uss.Add(us);

uss.Add(us);

StringTemplateGroup sg = new StringTemplateGroup("GroupTest");

sg.Definetemplate("RowRed",
"<tr class=red><td>$it.Name$</td><td>$it.Age$</td></tr>\n");

sg.Definetemplate("Rowblack",
"<tr class=black><td>$it.Name$</td><td>$it.Age$</td></tr>\n");

StringTemplate st = sg.Definetemplate("List",
"<table>$Item:RowRed(),Rowblack()$</table>");

st.SetAttribute("Item", uss);

Console.WriteLine(st.ToString());

}

#endregion

#region "条件判断"

private static void 条件判断()

{

StringTemplate st = new StringTemplate("当前用户登陆状态: $if(IsAdmin)$ 用户登陆成功! $else$ 用户没有登陆! $endif$");

st.SetAttribute("IsAdmin", true);

Console.WriteLine(st.ToString());

}

#endregion

private static void 从文件中创建模板()

{

StringTemplateGroup group = new StringTemplateGroup("myGroup", new LoadFileHtm(AppDomain.CurrentDomain.BaseDirectory+@"Template\") , typeof(DefaultTemplateLexer));

StringTemplate helloAgain = group.GetInstanceOf("homepage");

helloAgain.SetAttribute("title", "Welcome To StringTemplate");

helloAgain.SetAttribute("name", "World");

helloAgain.SetAttribute("friends", "Terence");

helloAgain.SetAttribute("friends", "Kunle");

helloAgain.SetAttribute("friends", "Micheal");

helloAgain.SetAttribute("friends", "Marq");

Console.WriteLine(helloAgain.ToString());

}

}

public class LoadFileHtm : StringTemplateLoader

{

/// <summary>

/// How are the files encoded (ascii, UTF8, ...)? You might want to read

/// UTF8 for example on a ascii machine.

/// </summary>

private Encoding encoding;

private FileSystemWatcher filesWatcher;

private HybridDictionary fileSet;

public LoadFileHtm()

: this(null, Encoding.Default, true)

{

}

public LoadFileHtm(string locationRoot)

: this(locationRoot, Encoding.Default, true)

{

}

public LoadFileHtm(string locationRoot, bool raiseExceptionForEmptyTemplate)

: this(locationRoot, Encoding.Default, raiseExceptionForEmptyTemplate)

{

}

public LoadFileHtm(string locationRoot, Encoding encoding)

: this(locationRoot, encoding, true)

{

}

public LoadFileHtm(string locationRoot, Encoding encoding, bool raiseExceptionForEmptyTemplate)

: base(locationRoot, raiseExceptionForEmptyTemplate)

{

if ((locationRoot == null) || (locationRoot.Trim().Length == 0))

{

this.locationRoot = AppDomain.CurrentDomain.BaseDirectory;

}

this.encoding = encoding;

fileSet = new HybridDictionary(true);

}

/// <summary>

/// Determines if the specified template has changed.

/// </summary>

/// <param name="templateName">template name</param>

/// <returns>True if the named template has changed</returns>

public override bool HasChanged(string templateName)

{

//string templateLocation = Path.Combine(LocationRoot, GetLocationFromTemplateName(templateName));

string templateLocation = string.Format("{0}/{1}", LocationRoot, GetLocationFromTemplateName(templateName)).Replace('\\', '/');

object o = fileSet[templateLocation];

if ((o != null))

{

return true;

}

return false;

}

/// <summary>

/// Loads the contents of the named StringTemplate.

/// </summary>

/// <param name="templateName">Name of the StringTemplate to load</param>

/// <returns>

/// The contexts of the named StringTemplate or null if the template wasn't found

/// </returns>

/// <exception cref="TemplateLoadException">Thrown if error prevents successful template load</exception>

protected override string InternalLoadTemplateContents(string templateName)

{

string templateText = null;

string templateLocation = null;

try

{

//templateLocation = Path.Combine(LocationRoot, GetLocationFromTemplateName(templateName));

templateLocation = string.Format("{0}/{1}", LocationRoot, GetLocationFromTemplateName(templateName)).Replace('\\', '/');

StreamReader br;

try

{

br = new StreamReader(templateLocation, encoding);

}

catch (FileNotFoundException)

{

return null;

}

catch (DirectoryNotFoundException)

{

return null;

}

catch (Exception ex)

{

throw new TemplateLoadException("Cannot open template file: " + templateLocation, ex);

}

try

{

templateText = br.ReadToEnd();

if ((templateText != null) && (templateText.Length > 0))

{

//templateText = templateText.Trim();

if (filesWatcher == null)

{

filesWatcher = new FileSystemWatcher(LocationRoot, "*.htm");

//filesWatcher.InternalBufferSize *= 2;

filesWatcher.NotifyFilter =

NotifyFilters.LastWrite

| NotifyFilters.Attributes

| NotifyFilters.Security

| NotifyFilters.Size

| NotifyFilters.CreationTime

| NotifyFilters.DirectoryName

| NotifyFilters.FileName;

filesWatcher.IncludeSubdirectories = true;

filesWatcher.Changed += new FileSystemEventHandler(OnChanged);

filesWatcher.Deleted += new FileSystemEventHandler(OnChanged);

filesWatcher.Created += new FileSystemEventHandler(OnChanged);

filesWatcher.Renamed += new RenamedEventHandler(OnRenamed);

filesWatcher.EnableRaisingEvents = true;

}

}

fileSet.Remove(templateLocation);

}

finally

{

if (br != null) ((IDisposable)br).Dispose();

br = null;

}

}

catch (ArgumentException ex)

{

string message;

if (templateText == null)

message = string.Format("Invalid file character encoding: {0}", encoding);

else

message = string.Format("The location root '{0}' and/or the template name '{1}' is invalid.", LocationRoot, templateName);

throw new TemplateLoadException(message, ex);

}

catch (IOException ex)

{

throw new TemplateLoadException("Cannot close template file: " + templateLocation, ex);

}

return templateText;

}

/// <summary>

/// Returns the location that corresponds to the specified template name.

/// </summary>

/// <param name="templateName">template name</param>

/// <returns>The corresponding template location or null</returns>

public override string GetLocationFromTemplateName(string templateName)

{

return templateName + ".htm";

}

/// <summary>

/// Returns the template name that corresponds to the specified location.

/// </summary>

/// <param name="templateName">template location</param>

/// <returns>The corresponding template name or null</returns>

public override string GetTemplateNameFromLocation(string location)

{

//return Path.ChangeExtension(location, string.Empty);

return Path.ChangeExtension(location, null);

}

#region FileSystemWatcher Events

private void OnChanged(object source, FileSystemEventArgs e)

{

string fullpath = e.FullPath.Replace('\\', '/');

fileSet[fullpath] = locationRoot;

}

private void OnRenamed(object source, RenamedEventArgs e)

{

string fullpath = e.FullPath.Replace('\\', '/');

fileSet[fullpath] = locationRoot;

fullpath = e.OldFullPath.Replace('\\', '/');

fileSet[fullpath] = locationRoot;

}

#endregion

}

public class Link

{

public string faqid;

public string faqtitle;

}

public class User

{

public string Name = "";

public string Age = "";

}

public static class FileHelp

{

public static string Read(string filename,string Dir)

{

filename = AppDomain.CurrentDomain.BaseDirectory + Dir + filename;

using(FileStream fs = new FileStream(filename,FileMode.Open,FileAccess.Read))

{

StreamReader sr = new StreamReader(fs,Encoding.Default);

return sr.ReadToEnd();

}

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: