2008年5月29日
stringTemplate是一个模板引擎,同时支持java,C#,Python. 大家可以从
http://www.stringtemplate.org/下载.
StringTemplate 语法说明
StringTemplate的语法是以$xxxx$来进行分割的. stringtemplate关键写是区分大小写的.
属性引用
名称属性
在模板中,这个是最常用的一个属性.用于显示文字.如下:
你的邮件地址:$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 called property. 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() applies bold() 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's application.
|
|
<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 like first(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, use length(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 !$
|
Comments, ignored by StringTemplate
|
- 把资源文件的生成操作设为嵌入的资源
- 然后将下面这行
[assembly: WebResource("NPao.Control.Resource.DateDropDownList.js", "text/javascript")]
添加到在assemblyinfo.cs中。其实这个语句放任何cs文件里,保证放在最高级namespace外就行
DateDropDownList.js是资源名字,比如项目的Default namespace是“NPao.Control”,
而文件DateDropDownList.js放在/Resource目录中,那么完整资源名就是NPao.Control.Resource.DateDropDownList.js
- 然后在程序中调用如下:
Image1.ImageUrl = this.Page.ClientScript.GetWebResourceUrl(this.GetType(), "wuChang.WebControls.images.MessagePanel_info.gif");
摘要: 最近在重构公司的电子商务网站,其中有个打折消费的功能.这里简单介绍下,比如,网站搞活动买二送一(以下称A),或者买二瓶其中价格低的一瓶半价(以下称B),.最初的设计是很粗糙的,因为之前网站是没有活动,后来增加一个活动,现在又要增加新的活动.从一开始的直接写代码,到后来的if else 判断打折条件,到现在又要添加新的打折,觉得这样的代码写的很粗糙,有种不爽的感觉.现在刚好有机会重构这里,就大概设计...
阅读全文
- 什么是对象?对象是一个自包含的实体,用一组可识别的特性和行为来标识.
- 什么是类? 类是具有相同属性和功能的对象的抽象的集合.
- 什么是实例?实例就是一个真实的对象.实例化就是创建对象的过程,用new关键字来创建.new关键字用来在内存中申请一个空间存放数据.
- 构造函数 默认一个无参数的构造函数,在new class的时候调用
- 方法重载 可在不改变原方法的基础上增加功能,方法名相同,参数类型或个数有所不同
- 字段是存储类要满足其设计所需要的数据,是与类相关的变量
- 属性是一个方法,但在调用他们的代码看来他是一个字段,属性适合以字段的方式使用方法调用的场合(使用属性可以设置符合要求的的字段的值)
- Public 允许任何类访问 private 仅允许同一个类的成员访问,他的子类也不能访问,定义变量时默认为private,protected的子类可以访问基类
- 封装:每个对象都包含它能进行操作所需要的所有信息,因此对象不必依赖其他对象来完成自己的操作 好处,减少耦合,内部可自由修改,具有清晰的对外接口
继承代表了一种 "is-a"的关系,还可以理解为是对被继承者的特殊化,除了具备被继承者的特性外,还具备有自己的独有个性,他定义类之间如何关联共享.
- 子类拥有父类非private的属性和功能
- 子类可以扩展父类没有的属性和功能
- 子类还可以以自己的方式实现父类的功能(方法重写)
- 子类不能继承基类的构造方法,只能被调用,可以使用base关键词
- 继承使得所有子类公共的部分都放在了父类,使得代码得到共享,避免重复
- 使得修改或扩展变得容易
- 缺点,父类变则子类不得不变,破坏封装,父类实现的细节暴露给子类
- 强耦合的关系,当2个类具备is-a的关系时,就可以考虑用继承
多态表示不同的对象可以执行相同的操作,但要通过他们自己的实现代码执行
- 子类以父类的身份出现
- 子类工作的时候以自己的方式来实现
- 子类以父类的身份出现的时候,子类特有的属性和方法不可以再使用
- 虚方法 virtual 为了让子类的实例完全接替来自父类的类成员,父类必须将该成员声明称虚拟的, 虚方法是按照运行时类型而非编译时类型进行动态绑定调用
- 子类可以选择使用override关键字,来实现替换父类的实现,方法重写
抽象类
- 类和方法前加上abstract,即抽象类和抽象方法
- 抽象类不能实例化
- 抽象方法是必须被子类重写的方法
- 如果类中包含有抽象方法,那么类就必须定义为抽象类,不论是否还包含有其他一般方法
- 抽象类拥有尽可能多的共同代码,拥有尽可能少的数据
- 抽象类通常代表一个抽象概念,他提供一个继承的出发点,当设计一个新的抽象类时,一定是用来继承的.
接口是把隐式公共方法和属性组合起来,以封装特定功能的一个集合
- 实现接口类就必须实现接口中的所以方法和属性
- 一个类可以实现多个接口
- 接口中的方法或属性前面不能有修饰符,方法没有方法体
抽象类与接口的区别
- 抽象类可以给出一些成员的实现,接口却不包含成员的实现
- 抽象类中的成员可以被子类实现,而接口的成员需要类完成实现
- 一个类只能继承一个抽象类,而可以接受多个接口
- 类是对对象的抽象,抽象类是对类的抽象,接口是对行为的抽象
- 如果行为跨越不同类的对象,可使用接口,对于一些相似的类对象,用继承抽象类
- 从设计角度讲,抽象类是从子类中发现了公共的东西,泛化出父类,然后子类继承父类,而接口是根本不知道子类的存在,方法如何实现还不确认,预先定义
- 通过重构改善既有代码设计
泛型是具有占位符的类接口结构和方法
- 使用泛型不需要装箱拆箱
委托与事件
- 委托是对函数的封装,可以当作给方法的特征指定一个名称.而事件是委托的一种特殊形式,当发生有意义的事情时,事件对象处理通知过程
- 委托是一种引用方法的类型,一旦为委托分配了方法,委托将与方法具有相同的行为
- 在发生其他类或对象关注的事情时,类或对象可通过事件通知他们
最近买了园子里一位大哥出的书,大话设计模式,之前也买过园子里的几本书,比如设计之道,道不远人等,怎么发现里面都有个道字
道不远人也是刚刚到手,还没来得及看,
大话设计模式已经由当当送出.
2本书拿到手上一比,道不远人那个厚啊,还是先从薄的开始看起吧^^
话说好记性不如烂笔头,之前看过很多书,当时看了现在就忘了,要记录下点学习笔记了,这个是开篇,要逐步记录下读书笔记
看看自己有没毅力哈
最近要给公司的电子商务网站添加个圈子的功能.网站功能本来就包含有新闻发布,会员管理,商品购物,后台管理等,现在又要再加上圈子的功能,网站项目越来越复
杂,每次编译生成的dll超过100k.这样每次修改任何一个功能中的任何一个小问题都要上传整个dll,并导致整个website的首次访问的重新编译.
之前也曾经想过,这些功能根据不同处于项目中的不同文件夹内,比如会员的会在member,后台管理的会在admin文件夹,新闻的会在news文件夹.这样的话如果vs支持按不同文件夹生成不同dll,那我每次修改不同功能的不同文件只要上传对应的dll就可以了,不再需要上传整个website的dll.
不过想法是美好的,事实是残酷的.vs并不支持这样的功能.所以在功能直接交互和文件共享并不多的功能上,我采取了重新建立一个projects的方法,比如把后台管理剥离出来,新建一个admin的website,这个新的projects放在website的根目录下,然后修改文件编译生成dll后的目录为..\bin并且删除项目中的web.config.编译后访问,呵呵,真的可以访问了,并且达到了拆分项目的要求.倒是并不完美,还有手动修改很多设置,并且这2个项目中不能共享相同的master,和usercontrol,甚至是图片,js等,如果直接使用相对路径,那么视图模式下将不能正常显示,如果vs直接提供新建子项目的功能并能解决共享这些文件,该有多好啊.
于是通过Google,找到一篇文章http://blogs.msdn.com/webdevtools/archive/2006/07/01/652986.aspx,Creating sub-projects in IIS with Web Application Projects,不幸的是文中提到的“Web Application Projects” add-in,我Download了,but can't install!
虽然这样的应用程序我们无法制作,但是我们可以按照他的思路自己修改配置啊.
发现他的方法,跟一开始我的做法是很类似的,不过他可以共享master和user control,为什么我的不能呢?
仔细翻看了一下,发现原来他在子项目中创建了虚拟目录比如 http://localhost/group,所以之前使用~/Group.Master,只能访问本项目中的master,而现在则可以访问根目录中的master了,试试usercontrol,也可以了,呵呵,原理奥妙都在这个虚拟目录中呀.
不过最后,还是觉得这样的方式不是很舒服,不知道大家有没什么好的办法,我在这里抛下砖.
本来想发在新手区的,但是我觉得这个应该是大部分程序员都会遇到的问题,把Web 应用程序分解为多个较小项目也有很多优点,不知道各位达人平时如何解决的?
如果大家觉得放在首页不合适的话,我也会移开.
本以为蜘蛛很简单,根据一个url,抓取到html内容,然后根据正则匹配数据入库.却发现,越看资料越复杂,蜘蛛应该根据抓取相似页面自动生成抓取模板,而且蜘蛛还要支持cookies和会自登录等多种协议.
页面解析方面,也不是简单的获得标题和内容那么简单,还要做dom解析,js解析,模拟浏览器的可视化抓取等等.
先从页面数据的抽取这方面入手研究吧.