[转载]最全的CSS浏览器兼容问题整理

mikel阅读(974)

[转载]最全的CSS浏览器兼容问题整理 – 华仔崽 – 博客园.

CSS 对浏览器的兼容性有时让人很头疼,或许当你了解当中的技巧跟原理,就会觉得也不是难事,从网上收集了IE7,6与Fireofx的兼容性处理方法并整理了 一下.对于web2.0的过度,请尽量用xhtml格式写代码,而且DOCTYPE 影响 CSS 处理,作为W3C的标准,一定要加DOCTYPE声 名.

CSS技巧

1.div的垂直居中问题

vertical-align:middle; 将行距增加到和整个DIV一样高 line-height:200px; 然后插入文字,就垂直居中了。缺点是要控制内容不要换行

2. margin加倍的问题

设置为float的div在ie下设置的margin会加倍。这是一个ie6都存在的bug。解决方案是在这个div里面加上display:inline;
例如:
<#div id=”imfloat”>
相应的css为
#IamFloat{
float:left;
margin:5px;/*IE下理解为10px*/
display:inline;/*IE下再理解为5px*/}

3.浮动ie产生的双倍距离

#box{ float:left; width:100px; margin:0 0 0 100px; //这种情况之下IE会产生200px的距离 display:inline; //使浮动忽略}
这里细说一下block与inline两个元素:block元素的特点是,总是在新行上开始,高度,宽度,行高,边距都可以控制(块元素);Inline元素的特点是,和其他元素在同一行上,不可控制(内嵌元素);
#box{ display:block; //可以为内嵌元素模拟为块元素 display:inline; //实现同一行排列的效果 diplay:table;

4 IE与宽度和高度的问题

IE 不认得min-这个定义,但实际上它把正常的width和height当作有min的情况来使。这样问题就大了,如果只用宽度和高度,正常的浏览器里这两 个值就不会变,如果只用min-width和min-height的话,IE下面根本等于没有设置宽度和高度。
比如要设置背景图片,这个宽度是比较重要的。要解决这个问题,可以这样:
#box{ width: 80px; height: 35px;}html>body #box{ width: auto; height: auto; min-width: 80px; min-height: 35px;}

5.页面的最小宽度

min -width是个非常方便的CSS命令,它可以指定元素最小也不能小于某个宽度,这样就能保证排版一直正确。但IE不认得这个,而它实际上把width当 做最小宽度来使。为了让这一命令在IE上也能用,可以把一个<div> 放到 <body> 标签下,然后为div指定一个类, 然后CSS这样设计:
#container{ min-width: 600px; width:expression(document.body.clientWidth < 600? “600px”: “auto” );}
第一个min-width是正常的;但第2行的width使用了JavaScript,这只有IE才认得,这也会让你的HTML文档不太正规。它实际上通过JavaScript的判断来实现最小宽度。

6.DIV浮动IE文本产生3象素的bug

左边对象浮动,右边采用外补丁的左边距来定位,右边对象内的文本会离左边有3px的间距.
#box{ float:left; width:800px;}
#left{ float:left; width:50%;}
#right{ width:50%;}
*html #left{ margin-right:-3px; //这句是关键}
<div id=”box”>
<div id=”left”></div>
<div id=”right”></div>
</div>

7.IE捉迷藏的问题

当div应用复杂的时候每个栏中又有一些链接,DIV等这个时候容易发生捉迷藏的问题。
有些内容显示不出来,当鼠标选择这个区域是发现内容确实在页面。 解决办法:对#layout使用line-height属性 或者给#layout使用固定高和宽。页面结构尽量简单。

8.float的div闭合;清除浮动;自适应高度;

① 例如:<#div id=”floatA” ><#div id=”floatB” ><#div id=” NOTfloatC” >这里的NOTfloatC并不希望继续平移,而是希望往下排。(其中floatA、floatB的属性已经设置为 float:left;)
这段代码在IE中毫无问题,问题出在FF。原因是NOTfloatC并非float标签,必须将float标签 闭合。在 <#div class=”floatB”> <#div class=”NOTfloatC”>之间加上 < #div class=”clear”>这个div一定要注意位置,而且必须与两个具有float属性的div同级,之间不能存在嵌套关系,否则会 产生异常。 并且将clear这种样式定义为为如下即可: .clear{ clear:both;}

②作为外部 wrapper 的 div 不要定死高度,为了让高度能自动适应,要在wrapper里面加上overflow:hidden; 当包含float的 box的时候,高度自动适应在IE下无效,这时候应该触发IE的layout私有属性(万恶的IE啊!)用zoom:1;可以做到,这样就达到了兼容。
例如某一个wrapper如下定义:
.colwrapper{ overflow:hidden; zoom:1; margin:5px auto;}

③对于排版,我们用得最多的css描述可能就是float:left.有的时候我们需要在n栏的float div后面做一个统一的背景,譬如:
<div id=”page”>
<div id=”left”></div>
<div id=”center”></div>
<div id=”right”></div>
</div>
比 如我们要将page的背景设置成蓝色,以达到所有三栏的背景颜色是蓝色的目的,但是我们会发现随着left center right的向下拉长,而 page居然保存高度不变,问题来了,原因在于page不是float属性,而我们的page由于要居中,不能设置成float,所以我们应该这样解决
<div id=”page”>
<div id=”bg” style=”float:left;width:100%”>
<div id=”left”></div>
<div id=”center”></div>
<div id=”right”></div>
</div>
</div>
再嵌入一个float left而宽度是100%的DIV解决之

④万能float 闭合(非常重要!)
关 于 clear float 的原理可参见 [How To Clear Floats Without Structural Markup],将以下 代码加入Global CSS 中,给需要闭合的div加上 class=”clearfix” 即可,屡试不爽.
/* Clear Fix */
.clearfix:after { content:”.”; display:block; height:0; clear:both; visibility:hidden; }
.clearfix { display:inline-block; }
/* Hide from IE Mac */
.clearfix {display:block;}
/* End hide from IE Mac */
/* end of clearfix */
或者这样设置:.hackbox{ display:table; //将对象作为块元素级的表格显示}

11.高度不适应

高度不适应是当内层对象的高度发生变化时外层高度不能自动进行调节,特别是当内层对象使用margin 或paddign 时。
例:
#box {background-color:#eee; }
#box p {margin-top: 20px;margin-bottom: 20px; text-align:center; }
<div id=”box”>
<p>p对象中的内容</p>
</div>
解决方法:在P对象上下各加2个空的div对象CSS代码:.1{height:0px;overflow:hidden;}或者为DIV加上border属性。

12 .IE6下为什么图片下有空隙产生

解 决这个BUG的方法也有很多,可以是改变html的排版,或者设置img 为display:block 或者设置vertical-align 属性为 vertical-align:top | bottom |middle |text-bottom 都可以解决.

13.如何对齐文本与文本输入框

加上 vertical-align:middle;
<style type=”text/css”>
<!–
input {
width:200px;
height:30px;
border:1px solid red;
vertical-align:middle;
}
–>
</style>

14.web标准中定义id与class有什么区别吗

一.web标准中是不容许重复ID的,比如 div id=”aa”   不容许重复2次,而class 定义的是类,理论上可以无限重复, 这样需要多次引用的定义便可以使用他.

二.属性的优先级问题
ID 的优先级要高于class,看上面的例子

三.方便JS等客户端脚本,如果在页面中要对某个对象进行脚本操作,那么可以给他定义一个ID,否则只能利用遍历页面元素加上指定特定属性来找到它,这是相对浪费时间资源,远远不如一个ID来得简单.

15. LI中内容超过长度后以省略号显示的方法

此方法适用与IE与OP浏览器

<style type=”text/css”>
<!–
li {
width:200px;
white-space:nowrap;
text-overflow:ellipsis;
-o-text-overflow:ellipsis;
overflow: hidden;
}

–>
</style>

16.为什么web标准中IE无法设置滚动条颜色了

解决办法是将body换成html
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”>
<meta http-equiv=”Content-Type” content=”text/html; charset=gb2312″ />
<style type=”text/css”>
<!–
html {
scrollbar-face-color:#f6f6f6;
scrollbar-highlight-color:#fff;
scrollbar-shadow-color:#eeeeee;
scrollbar-3dlight-color:#eeeeee;
scrollbar-arrow-color:#000;
scrollbar-track-color:#fff;
scrollbar-darkshadow-color:#fff;
}
–>
</style>

17.为什么无法定义1px左右高度的容器

IE6下这个问题是因为默认的行高造成的,解决的方法也有很多,例如:overflow:hidden | zoom:0.08 | line-height:1px

18.怎么样才能让层显示在FLASH之上呢

解决的办法是给FLASH设置透明
<param name=”wmode” value=”transparent” />

19.怎样使一个层垂直居中于浏览器中

这里我们使用百分比绝对定位,与外补丁负值的方法,负值的大小为其自身宽度高度除以二
<style type=”text/css”>
<!–
div {
position:absolute;
top:50%;
lef:50%;
margin:-100px 0 0 -100px;
width:200px;
height:200px;
border:1px solid red;
}
–>
</style>

FF与IE

1. Div居中问题

div设置 margin-left, margin-right 为 auto 时已经居中,IE 不行,IE需要设定body居中,首先在父级元素定义text-algin: center;这个的意思就是在父级元素内的内容居中。

2.链接(a标签)的边框与背景

a 链接加边框和背景色,需设置 display: block, 同时设置 float: left 保证不换行。参照 menubar, 给 a 和 menubar 设置高度是为了避免底边显示错位, 若不设 height, 可以在 menubar 中插入一个空格。

3.超链接访问过后hover样式就不出现的问题

被点击访问过的超链接样式不在具有hover和active了,很多人应该都遇到过这个问题,解决方法是改变CSS属性的排列顺序: L-V-H-A
Code:
<style type=”text/css”>
<!–
a:link {}
a:visited {}
a:hover {}
a:active {}
–>
</style>

4. 游标手指cursor

cursor: pointer 可以同时在 IE FF 中显示游标手指状, hand 仅 IE 可以

5.UL的padding与margin

ul标签在FF中默认是有padding值的,而在IE中只有margin默认有值,所以先定义 ul{margin:0;padding:0;}就能解决大部分问题

6. FORM标签

这 个标签在IE中,将会自动margin一些边距,而在FF中margin则是0,因此,如果想显示一致,所以最好在css中指定margin和 padding,针对上面两个问题,我的css中一般首先都使用这样的样式ul,form{margin:0;padding:0;}给定义死了,所以后 面就不会为这个头疼了.

7. BOX模型解释不一致问题

在FF和IE 中的BOX模型解释不一致导致相差2px解决方法:div{margin:30px!important;margin:28px;} 注意这两个 margin的顺序一定不能写反, important这个属性IE不能识别,但别的浏览器可以识别。所以在IE下其实解释成这样: div {maring:30px;margin:28px}重复定义的话按照最后一个来执行,所以不可以只写margin:xx px!important;
#box{ width:600px; //for ie6.0- w\idth:500px; //for ff+ie6.0}
#box{ width:600px!important //for ff width:600px; //for ff+ie6.0 width /**/:500px; //for ie6.0-}

8.属性选择器(这个不能算是兼容,是隐藏css的一个bug)

p[id]{}div[id]{}
这个对于IE6.0和IE6.0以下的版本都隐藏,FF和OPera作用.属性选择器和子选择器还是有区别的,子选择器的范围从形式来说缩小了,属性选择器的范围比较大,如p[id]中,所有p标签中有id的都是同样式的.

9.最狠的手段 – !important;

如果实在没有办法解决一些细节问题,可以用这个方法.FF对于”!important”会自动优先解析,然而IE则会忽略.如下
.tabd1{
background:url(/res/images/up/tab1.gif) no-repeat 0px 0px !important; /*Style for FF*/
background:url(/res/images/up/tab1.gif) no-repeat 1px 0px; /* Style for IE */}
值得注意的是,一定要将xxxx !important 这句放置在另一句之上,上面已经提过

10.IE,FF的默认值问题

或 许你一直在抱怨为什么要专门为IE和FF写不同的CSS,为什么IE这样让人头疼,然后一边写css,一边咒骂那个可恶的M$ IE.其实对于css的标 准支持方面,IE并没有我们想象的那么可恶,关键在于IE和FF的默认值不一样而已,掌握了这个技巧,你会发现写出兼容FF和IE的css并不是那么困 难,或许对于简单的css,你完全可以不用”!important”这个东西了。
我们都知道,浏览器在显示网页的时候,都会根据网页的 css样式表来决定如何显示,但是我们在样式表中未必会将所有的元素都进行了具体的描述,当然也没有必要那么做,所以对于那些没有描述的属性,浏览器将采 用内置默认的方式来进行显示,譬如文字,如果你没有在css中指定颜色,那么浏览器将采用黑色或者系统颜色来显示,div或者其他元素的背景,如果在 css中没有被指定,浏览器则将其设置为白色或者透明,等等其他未定义的样式均如此。所以有很多东西出现FF和IE显示不一样的根本原因在于它们的默认显 示不一样,而这个默认样式该如何显示我知道在w3中有没有对应的标准来进行规定,因此对于这点也就别去怪罪IE了。

11.为什么FF下文本无法撑开容器的高度

标准浏览器中固定高度值的容器是不会象IE6里那样被撑开的,那我又想固定高度,又想能被撑开需要怎样设置呢?办法就是去掉height设置min-height:200px;   这里为了照顾不认识min-height的IE6 可以这样定义:

{
height:auto!important;
height:200px;
min-height:200px;
}

12.FireFox下如何使连续长字段自动换行

众所周知IE中直接使用 word-wrap:break-word 就可以了, FF中我们使用JS插入的方法来解决

<style type=”text/css”>
<!–
div {
width:300px;
word-wrap:break-word;
border:1px solid red;
}
–>
</style>

<div id=”ff”>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</div>

<scrīpt type=”text/javascrīpt”>
/* <![CDATA[ */
function toBreakWord(el, intLen){
var ōbj=document.getElementById(el);
var strContent=obj.innerHTML;
var strTemp=””;
while(strContent.length>intLen){
strTemp+=strContent.substr(0,intLen)+” “;
strContent=strContent.substr(intLen,strContent.length);
}
strTemp+=” “+strContent;
obj.innerHTML=strTemp;
}
if(document.getElementById   &&   !document.all)   toBreakWord(“ff”, 37);
/* ]]> */
</scrīpt>

13.为什么IE6下容器的宽度和FF解释不同呢

<?xml version=”1.0″ encoding=”gb2312″?>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”>
<meta http-equiv=”Content-Type” content=”text/html; charset=gb2312″ />
<style type=”text/css”>
<!–
div {
cursor:pointer;
width:200px;
height:200px;
border:10px solid red
}
–>
</style>
<div ōnclick=”alert(this.offsetWidth)”>让FireFox与IE兼容</div>

问 题的差别在于容器的整体宽度有没有将边框(border)的宽度算在其内,这里IE6解释为200PX ,而FF则解释为220PX,那究竟是怎么导致的 问题呢?大家把容器顶部的xml去掉就会发现原来问题出在这,顶部的申明触发了IE的qurks mode,关于qurks mode、 standards mode的相关知识,请参考:http: //www.microsoft.com/china/msdn/library/webservices/ASP.NET/
ASPNETusStan.mspx?mfr=true

IE6,IE7,FF

IE7.0 出来了,对CSS的支持又有新问题。浏览器多了,网页兼容性更差了,疲于奔命的还是我们 ,为解决IE7.0的兼容问题,找来了下面这篇文章: 现在我大 部分都是用!important来hack,对于ie6和firefox测试可以正常显示,但是ie7对!important可以正确解释,会导致页面没 按要求显示!下面是三个浏览器的兼容性收集.

第一种,是CSS HACK的方法

height:20px; /*For Firefox*/
*height:25px; /*For IE7 & IE6*/
_height:20px; /*For IE6*/

注意顺序。

这样也属于CSS HACK,不过没有上面这样简洁。
#example { color: #333; } /* Moz */
* html #example { color: #666; } /* IE6 */
*+html #example { color: #999; } /* IE7 */

第二种,是使用IE专用的条件注释

<!–其他浏览器 –>
<link rel=”stylesheet” type=”text/css” href=”css.css” />

<!–[if IE 7]>
<!– 适合于IE7 –>
<link rel=”stylesheet” type=”text/css” href=”ie7.css” />
<![endif]–>

<!–[if lte IE 6]>
<!– 适合于IE6及一下 –>
<link rel=”stylesheet” type=”text/css” href=”ie.css” />
<![endif]–>

第三种,css filter的办法,以下为经典从国外网站翻译过来的。.

新建一个css样式如下:
#item {
width: 200px;
height: 200px;
background: red;
}

新建一个div,并使用前面定义的css的样式:
<div id=”item”>some text here</div>

在body表现这里加入lang属性,中文为zh:
<body lang=”en”>

现在对div元素再定义一个样式:
*:lang(en) #item{
background:green !important;
}

这样做是为了用!important覆盖原来的css样式,由于:lang选择器ie7.0并不支持,所以对这句话不会有任何作用,于是也达到了ie6.0下同样的效果,但是很不幸地的是,safari同样不支持此属性,所以需要加入以下css样式:
#item:empty {
background: green !important
}
:empty选择器为css3的规范,尽管safari并不支持此规范,但是还是会选择此元素,不管是否此元素存在,现在绿色会现在在除ie各版本以外的浏览器上。

对IE6和FF的兼容可以考虑以前的!important 个人比较喜欢用第一种,简洁,兼容性比较好

好记性不如烂博客

[转载]Android编程获取网络连接状态(3G/Wifi)及调用网络配置界面

mikel阅读(847)

[转载]Android编程获取网络连接状态(3G/Wifi)及调用网络配置界面 – Android平台开发技术 – 博客园.

获取网络连接状态

随着3G和Wifi的推广,越来越多的Android应用程序需要调用网络资源,检测网络连接状态也就成为网络应用程序所必备的功能。

Android平台提供了ConnectivityManager 类,用于网络连接状态的检测。

Android开发文档这样描述ConnectivityManager 的作用:

Class that answers queries about the state of network connectivity. It also notifies applications when network connectivity changes. Get an instance of this class by callingContext.getSystemService(Context.CONNECTIVITY_SERVICE).

The primary responsibilities of this class are to:

  1. Monitor network connections (Wi-Fi, GPRS, UMTS, etc.)
  2. Send broadcast intents when network connectivity changes
  3. Attempt to “fail over” to another network when connectivity to a network is lost
  4. Provide an API that allows applications to query the coarse-grained or fine-grained state of the available networks
下面这个简单的例子 checkNetworkInfo() 说明了如何编程获取Android手机的当前网络状态

private void checkNetworkInfo() { ConnectivityManager conMan = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); //mobile 3G Data Network State mobile = conMan.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState(); txt3G.setText(mobile.toString()); //显示3G网络连接状态 //wifi State wifi = conMan.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState(); txtWifi.setText(wifi.toString()); //显示wifi连接状态 }

注:


据Android的安全机制,在使用ConnectivityManager时,必须在AndroidManifest.xml中添加<uses-
permission android:name=”android.permission.ACCESS_NETWORK_STATE” />
否则无法获得系统的许可。

运行结果(关闭3G及wifi网络连接的状态下)

调用Android手机的网络配置界面

使用过Android手机上的手机QQ的朋友,应该知道,当QQ启动时,如果没有有效的网络连接,QQ会提示转入手机的网络配置界面。这是如何实现的呢。其实很简单啦

private void checkNetworkInfo() { ConnectivityManager conMan = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); //mobile 3G Data Network State mobile = conMan.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState(); txt3G.setText(mobile.toString()); //wifi State wifi = conMan.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState(); txtWifi.setText(wifi.toString()); //如果3G网络和wifi网络都未连接,且不是处于正在连接状态 则进入Network Setting界面 由用户配置网络连接 if(mobile==State.CONNECTED||mobile==State.CONNECTING) return; if(wifi==State.CONNECTED||wifi==State.CONNECTING) return; startActivity(new Intent(Settings.ACTION_WIRELESS_SETTINGS));//进入无线网络配置界面 //startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS)); //进入手机中的wifi网络设置界面 }

运行结果(关闭3G及wifi网络连接的状态下),程序转入无线网络配置界面

startActivity(new Intent(Settings.ACTION_WIRELESS_SETTINGS));//进入无线网络配置界面

如果调用

startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS)); //直接进入手机中的wifi网络设置界面

则直接进入手机中的wifi网络设置界面

在wifi网络连接后 运行该程序

我们可以看到 wi-fi 状态为已连接(CONNECTED).

[转载]如何利用C#批量注册QQ邮箱

mikel阅读(1277)

[转载]如何利用C#批量注册QQ邮箱 – wuhuacong(伍华聪)的专栏 – 博客园.

在上篇随笔《如何使用C#实现QQ号码的申请》 有介绍如何利用C#实现QQ号码的批量申请功能,其实腾讯还提供了一个注册QQ邮箱伴随有QQ号码的注册方式,就是QQ邮箱的注册,QQ邮箱的批量注册, 在很多场合需要用到,如注册淘宝账号,或者用来发送邮件,做营销加群,然后发送群邮件等等操作,注册QQ邮箱的界面如下图所示:

相对来说,QQ邮件的注册会比较容易一些,腾讯没有那么多变态古怪的加密处理方式,是比较正常的POST操作处理。

关键申请代码如下所示:

postData.AppendFormat(email={0}&nick={0}, randomUser, randomUser.Length > 10 ? randomUser.Substring(10) : randomUser);
postData.AppendFormat(
&age=1993&age_month=8&age_day=23&regsex=1);
postData.AppendFormat(
&password_1={0}&password_2={0}, qqDefaultPass);
postData.AppendFormat(
&Country=6&State=26&City=7);
postData.AppendFormat(
&validecode={0}&regqqmail=1&asdfg={1}&, this.txtVerifyCode.Text, asdfg);

string tempUrl = http://emailreg.qq.com/cgi-bin/signup/srv_tj?type=54796&seed=0. + GetRandomNumber();
string temp = httpHelper.GetHtml(tempUrl, cookieReg, tempUrl);
Thread.Sleep(
100);

string content = httpHelper.GetHtml(postUrl, cookieReg, postData.ToString(), true, refer);
if (content.Contains(恭喜您,申请成功))
{
string qq = httpHelper.GetHiddenKeyValue(content, uin);

re = new Regex(您申请的Email帐号为:<strong>(?<email>.*?)</strong>, RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.IgnorePatternWhitespace);
mc
= re.Match(content);
string email = “”;
if (mc.Success)
{
email
= mc.Groups[1].Value;
}

SuccessCount++;//成功计数
AddToList(string.Format(qq:{0} email:{1}, qq, email));
SetTips(
string.Format(恭喜您,申请到QQ邮件:{0} Email:{1}, qq, email));

int redialCount = Convert.ToInt32(this.txtReDailCount.Value);
if (redialCount > 0 && (SuccessCount % redialCount == 0))
{
btnRedail_Click(
null, null);//重新拨号
}
}
else
{
string error = 申请失败,请重试;
if (content.IndexOf(此IP申请的操作过于频繁) > 0)
{
error
= 此IP申请的操作过于频繁;
}
else if (content.IndexOf(验证码错误) > 0)
{
error
= 验证码错误;
}
SetTips(error);
}

软件实现的效果如下所示:

腾讯一般一天一个IP只是允许注册几个号码,如果太过频繁,容易被封锁一段时间,这个时候,就可以利用快速拨号方式,重新更换IP地址,然后又是好汉一条,非常酷爽,哈哈。

[转载]ASP.NET MVC中的扩展点(七)视图及视图引擎

mikel阅读(1035)

[转载]MVC中的扩展点(七)视图及视图引擎 – xfrog – 博客园.

我们知道在MVC框架中,最终通过ActionResult来生成应答内容。上一篇中我们介绍了MVC中默认的结果类型,本章我们将详细介绍ViewResult及PartialViewResult,了解MVC是如何通过视图来生成应答内容的。

MVC默认的视图被称为Web Forms视图引擎,原因在于它的视图文件使用与ASP.NET Web Forms相同的文件类型(.aspx .ascx),并且使用ASP.NET的页面解析器来解释视图文件内容。也在于,我们在编写视图文件时,可以完全像编写aspx页面文件一样,使用智能提 示功能及内联代码等。

与传统ASP.NET页面一样,在运行时内建的页面编译器会将我们的aspx或ascx文件转换为标准的.NET类,假设我们的视图内容为:

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>
 <div>
 <%=Html.Label("Hello World!") %>
<%
     using (Html.BeginForm())
    {
    }
%>
 </div>
 
.codearea { color: black; background-color: white; line-height: 18px; border: 1px solid rgb(79, 129, 189); margin: 0pt; width: auto ! important; overflow: auto; text-align: left; font-size: 12px; font-family: “Courier New”,”Consolas”,”Fixedsys”,”BitStream Vera Sans Mono”,courier,monospace,serif; }.codearea pre { color: black; line-height: 18px; padding: 0pt 0pt 0pt 12px ! important; margin: 0em; background-color: rgb(255, 255, 255) ! important; }.linewrap pre { white-space: pre-wrap; word-wrap: break-word; }.codearea pre.alt { background-color: rgb(247, 247, 255) ! important; }.codearea .lnum { color: rgb(79, 129, 189); line-height: 18px; }

页面编译器会将此视图转换为类似以下的类:

public class views_home_index_aspx : ViewPage, IRequiresSessionState, IHttpHandler
 {
    private void @__BuildControlTree(views_home_index_aspx @__ctrl)
    {
        this.InitializeCulture();
        @__ctrl.SetRenderMethodDelegate(new System.Web.UI.RenderMethod(this.@__Render));
    }

    private void @__Render(System.Web.UI.HtmlTextWriter @__w, System.Web.UI.Control parameterContainer)
    {
        @__w.Write("\r\n<div>\r\n");
        @__w.Write(Html.Label("Hello World!"));
        @__w.Write("\r\n");
        using (Html.BeginForm())
        {
        }
        @__w.Write("\r\n</div>\r\n");
    }
}

.codearea { color: black; background-color: white; line-height: 18px; border: 1px solid rgb(79, 129, 189); margin: 0pt; width: auto ! important; overflow: auto; text-align: left; font-size: 12px; font-family: “Courier New”,”Consolas”,”Fixedsys”,”BitStream Vera Sans Mono”,courier,monospace,serif; }.codearea pre { color: black; line-height: 18px; padding: 0pt 0pt 0pt 12px ! important; margin: 0em; background-color: rgb(255, 255, 255) ! important; }.linewrap pre { white-space: pre-wrap; word-wrap: break-word; }.codearea pre.alt { background-color: rgb(247, 247, 255) ! important; }.codearea .lnum { color: rgb(79, 129, 189); line-height: 18px; }

根据此类,生成的页面HTML源代码如下:


<div>
<label for="Hello World!">Hello World!</label>
<form action="/" method="post"></form>
</div>
 

.codearea { color: black; background-color: white; line-height: 18px; border: 1px solid rgb(79, 129, 189); margin: 0pt; width: auto ! important; overflow: auto; text-align: left; font-size: 12px; font-family: “Courier New”,”Consolas”,”Fixedsys”,”BitStream Vera Sans Mono”,courier,monospace,serif; }.codearea pre { color: black; line-height: 18px; padding: 0pt 0pt 0pt 12px ! important; margin: 0em; background-color: rgb(255, 255, 255) ! important; }.linewrap pre { white-space: pre-wrap; word-wrap: break-word; }.codearea pre.alt { background-color: rgb(247, 247, 255) ! important; }.codearea .lnum { color: rgb(79, 129, 189); line-height: 18px; }

显然,在转换时,编译器将非代码内容转换为Response.Write(…)的形式,即直接将内容写入Response,将<%=表达式%& gt;转换为Response.Write(表达式)的形式,即将表达式的返回值写入Response,将<%表达式%>中的表达式直接按代 码写入,即直接执行代码,不写入Response。

从技术上讲,ASP.NET中的aspx是通过PageParserFilter抽象类来控制类代码的生成,在MVC中,MVC实现了自己的解析 器:ViewTypeParserFilter,通过它控制将视图文件转换为标准的.NET类的行为。MVC不使用ASP.NET默认解析器的原因在于默 认的解析器不支持泛型,即aspx不能从泛型基类中继承,而ViewTypeParserFilter解除了此限制。当我们生成一个MVC项目后,在 Views目录下包含了一个Web.config配置文件,从中可以看到MVC已经通过pages的pageParserFilterType项将此目录 下的默认页面解析器指定为ViewTypeParserFilter。

另外,视图文件与传统的aspx页面文件的一种重要不同点在于,传统页面从Page类继承,而视图是从MVC框架中的ViewPage类继承,本质上 ViewPage从Page继承,并在Page类基础针对MVC进行了扩展,这也是我们为什么可以在视图中使用模型对象、Html、Ajax等辅助类的原 因:

ViewPage

ViewPage<TModel>是ViewPage的泛型,在创建视图时,通过指定TModel的类型,从而实现强类型的ViewPage。

MVC视图引擎架构

视图引擎的执行方式很简单:通过ViewEngines.FindView根据当前的ControllerContext找出适当的视图引擎及视图,然后调用视图的Render方法生成应答内容,最后通过视图引擎的ReleaseView方法是否视图资源:

ViewActivity

MVC默认的Web Forms视图引擎类图如下:

ViewClass

IView、IViewEngine、ViewEngineResult是视图引擎的核心,IView接口负责视图的渲染,IViewEngine负责找出合适的视图文件,ViewEngineResult是对IView和IViewEngine的封装。

ViewEngineCollection表示一个IViewEngine集合,MVC提供向集合添加视图引擎的方法,并提供FindView、 FindPartialView方法,从集合项中找出与当前ControllerContext匹配的ViewEngineResult。

ViewEngines是一个静态类,其内部封装了一个ViewEngineCollection,构成了MVC框架默认的视图引擎集合,默认下,该结合仅包含一个Web Forms引擎。我们可通过视图引擎集合上的方法向其添加自定义的视图引擎。

WebFormViewEngine是IViewEngine的一个实现,表示一个Web Forms视图引擎。

WebFormView是IView的一个实现,表示一个Web Forms视图,其内部Render方法,将实例化一个通过视图aspx文件转换而来的类型。通过该类型将试图文件渲染为最终的应答结果。

第三方视图引擎

MVC视图引擎有不少开源项目,比较完善的有以下几种:

1、Spark View Engine:

官网:http://sparkviewengine.com/ 下载:http://sparkviewengine.codeplex.com/

2、NHaml View Engine

官网:http://code.google.com/p/nhaml/ 下载:http://code.google.com/p/nhaml/downloads/list

3、Razor:

此引擎有MVC同一团队开发,官网:http://www.asp.net/mvc 或者 http://www.asp.net/WebMatrix

每一个视图引擎都有自己不同的语法规则,对此本文不做介绍,请参考官方文档。另外,关于这几个引擎的粗略介绍,可参考以下博客:http://blogs.msdn.com/b/coding4fun/archive/2010/10/04/10070953.aspx

下面以Spark视图引擎为例,简要介绍第三方视图引擎的使用步骤:

1、下载Spark视图引擎并解压

2、新建一空的MVC项目,并添加对Spark.dll及Spark.Web.Mvc.dll的引用

3、修改Global.asax.cs,在Application_Start过程中想默认视图引擎集合中添加Spark视图引擎

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    RegisterRoutes(RouteTable.Routes);
    ViewEngines.Engines.Add(new SparkViewFactory());
}

.codearea { color: black; background-color: white; line-height: 18px; border: 1px solid rgb(79, 129, 189); margin: 0pt; width: auto ! important; overflow: auto; text-align: left; font-size: 12px; font-family: “Courier New”,”Consolas”,”Fixedsys”,”BitStream Vera Sans Mono”,courier,monospace,serif; }.codearea pre { color: black; line-height: 18px; padding: 0pt 0pt 0pt 12px ! important; margin: 0em; background-color: rgb(255, 255, 255) ! important; }.linewrap pre { white-space: pre-wrap; word-wrap: break-word; }.codearea pre.alt { background-color: rgb(247, 247, 255) ! important; }.codearea .lnum { color: rgb(79, 129, 189); line-height: 18px; }4、添加一个HomeController:

显示行号 复制代码 HomeController
  1. public class HomeController : Controller
    
  2.  {
    
  3.     private List<Product> products = new List<Product>()
    
  4.     {
    
  5.         new Product(){ID="0001", Name = "测a试?产ú品·1", Price=1},
    
  6.         new Product(){ID="0002", Name = "测a试?产ú品·2", Price=1}
    
  7.     };
    
  8.     public ActionResult Index()
    
  9.     {
    
  10.         ViewData["products"] = products;
    
  11.         return View();
    
  12.     }
    
  13. }
    

.src_container { background-color: rgb(231, 229, 220); width: 99%; overflow: hidden; margin: 12px 0pt ! important; padding: 0px 3px 3px 0px; }.src_container .titlebar { background-color: rgb(212, 223, 255); border-width: 1px 1px 0pt; border-style: solid solid none; border-color: rgb(79, 129, 189) rgb(79, 129, 189) -moz-use-text-color; padding: 3px 24px; margin: 0pt; width: auto; line-height: 120%; overflow: hidden; text-align: left; font-size: 12px; }.src_container .toolbar { display: inline; font-weight: normal; font-size: 100%; float: right; color: rgb(0, 0, 255); text-align: left; overflow: hidden; }.toolbar span.button { display: inline; font-weight: normal; font-size: 100%; color: rgb(0, 0, 255); text-align: left; overflow: hidden; cursor: pointer; }.src_container div.clientarea { background-color: white; border: 1px solid rgb(79, 129, 189); margin: 0pt; width: auto ! important; height: auto; overflow: auto; text-align: left; font-size: 12px; font-family: “Courier New”,”Consolas”,”Fixedsys”,courier,monospace,serif; }.src_container ol.mainarea { padding: 0pt 0pt 0pt 52px; margin: 0pt; background-color: rgb(247, 247, 255) ! important; }.number_show { padding-left: 52px ! important; list-style: decimal outside none ! important; }.number_show li { list-style: decimal outside none ! important; border-left: 1px dotted rgb(79, 129, 189); }.number_hide { padding-left: 0px ! important; list-style-type: none ! important; }.number_hide li { list-style-type: none ! important; border-left: 0px none; }ol.mainarea li { display: list-item ! important; font-size: 12px ! important; margin: 0pt ! important; line-height: 18px ! important; padding: 0pt 0pt 0pt 0px ! important; background-color: rgb(247, 247, 255) ! important; color: rgb(79, 129, 189); }ol.mainarea li pre { color: black; line-height: 18px; padding: 0pt 0pt 0pt 12px ! important; margin: 0em; background-color: rgb(255, 255, 255) ! important; }.linewrap ol.mainarea li pre { white-space: pre-wrap; word-wrap: break-word; }ol.mainarea li pre.alt { background-color: rgb(247, 247, 255) ! important; }5、在Models下建立一个Product类

显示行号 复制代码 Product
  1. public class Product
    
  2. {
    
  3.     public string ID { get; set; }
    
  4.     public string Name { get; set; }
    
  5.     public string Description { get; set; }
    
  6.     public decimal Price { get; set; }
    
  7. }
    

.src_container { background-color: rgb(231, 229, 220); width: 99%; overflow: hidden; margin: 12px 0pt ! important; padding: 0px 3px 3px 0px; }.src_container .titlebar { background-color: rgb(212, 223, 255); border-width: 1px 1px 0pt; border-style: solid solid none; border-color: rgb(79, 129, 189) rgb(79, 129, 189) -moz-use-text-color; padding: 3px 24px; margin: 0pt; width: auto; line-height: 120%; overflow: hidden; text-align: left; font-size: 12px; }.src_container .toolbar { display: inline; font-weight: normal; font-size: 100%; float: right; color: rgb(0, 0, 255); text-align: left; overflow: hidden; }.toolbar span.button { display: inline; font-weight: normal; font-size: 100%; color: rgb(0, 0, 255); text-align: left; overflow: hidden; cursor: pointer; }.src_container div.clientarea { background-color: white; border: 1px solid rgb(79, 129, 189); margin: 0pt; width: auto ! important; height: auto; overflow: auto; text-align: left; font-size: 12px; font-family: “Courier New”,”Consolas”,”Fixedsys”,courier,monospace,serif; }.src_container ol.mainarea { padding: 0pt 0pt 0pt 52px; margin: 0pt; background-color: rgb(247, 247, 255) ! important; }.number_show { padding-left: 52px ! important; list-style: decimal outside none ! important; }.number_show li { list-style: decimal outside none ! important; border-left: 1px dotted rgb(79, 129, 189); }.number_hide { padding-left: 0px ! important; list-style-type: none ! important; }.number_hide li { list-style-type: none ! important; border-left: 0px none; }ol.mainarea li { display: list-item ! important; font-size: 12px ! important; margin: 0pt ! important; line-height: 18px ! important; padding: 0pt 0pt 0pt 0px ! important; background-color: rgb(247, 247, 255) ! important; color: rgb(79, 129, 189); }ol.mainarea li pre { color: black; line-height: 18px; padding: 0pt 0pt 0pt 12px ! important; margin: 0em; background-color: rgb(255, 255, 255) ! important; }.linewrap ol.mainarea li pre { white-space: pre-wrap; word-wrap: break-word; }ol.mainarea li pre.alt { background-color: rgb(247, 247, 255) ! important; }
6、修改web.config,在configSections下添加spark配置节:

<section name="spark" type="Spark.Configuration.SparkSectionHandler, Spark"/>

7、在web.config中配置spark(如默认的命名空间引用):

  <spark>
    <compilation debug="true" defaultLanguage="CSharp" />
    <pages automaticEncoding="true" >
      <namespaces>
        <add namespace="System"/>
        <add namespace="System.Collections.Generic"/>
        <add namespace="System.Linq"/>
        <add namespace="System.Web"/>
        <add namespace="System.Web.Mvc"/>
        <add namespace="System.Web.Mvc.Html"/>
      </namespaces>
    </pages>
  </spark>

8、在Views下创建Home目录,并在此目录下添加Index.spark视图模板文件:

<viewdata products="IList[[Models.Product]]"/>
<div each="var product in products">
    <h2>${product.Name}</h2>
</div>

.codearea { color: black; background-color: white; line-height: 18px; border: 1px solid rgb(79, 129, 189); margin: 0pt; width: auto ! important; overflow: auto; text-align: left; font-size: 12px; font-family: “Courier New”,”Consolas”,”Fixedsys”,”BitStream Vera Sans Mono”,courier,monospace,serif; }.codearea pre { color: black; line-height: 18px; padding: 0pt 0pt 0pt 12px ! important; margin: 0em; background-color: rgb(255, 255, 255) ! important; }.linewrap pre { white-space: pre-wrap; word-wrap: break-word; }.codearea pre.alt { background-color: rgb(247, 247, 255) ! important; }.codearea .lnum { color: rgb(79, 129, 189); line-height: 18px; }

说明:本例仅演示如何使用第三方视图引擎,如果想详细了解Spark视图引擎,请访问官方网站

源代码下载

[转载]Android XML解析

mikel阅读(909)

[转载]Android XML解析 – Feisky – 博客园.

Android平台上可以使用Simple API for XML(SAX) 、 Document Object Model(DOM)和Android附带的pull解析器解析XML文件。

下面是本例子要解析的XML文件:

文件名称:itcast.xml

<?xml version=”1.0″ encoding=”UTF-8″?>

<persons>

<person id=”23″>

<name>李明</name>

<age>30</age>

</person>

<person id=”20″>

<name>李向梅</name>

<age>25</age>

</person>

</persons>

例子定义了一个javabean用于存放上面解析出来的xml内容, 这个javabean为Person,代码:

public class Person {

private Integer id;

private String name;

private Short age;

public Integer getId() {

return id;

}

public void setId(Integer id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public Short getAge() {

return age;

}

public void setAge(Short age) {

this.age = age;

}

}

使用SAX读取XML文件

SAX是一个解析速度快并且占用内存少的xml解析器,非常适合用于Android等移动设备。 SAX 解析XML文件采用的是事件驱动,也就是说,它并不需要解析完整个文档,在按内容顺序解析文档的过程中,SAX会判断当前读到的字符是否合法XML语法中 的某部分,如果符合就会触发事件。所谓事件,其实就是一些回调(callback)方法,这些方法(事件)定义在ContentHandler接口。

下面是一些ContentHandler接口常用的方法:

  • startDocument() 当遇到文档的开头的时候,调用这个方法,可以在其中做一些预处理的工作。
  • endDocument() 和上面的方法相对应,当文档结束的时候,调用这个方法,可以在其中做一些善后的工作。
  • startElement(String namespaceURI, String localName, String qName, Attributes atts) 当 读到一个开始标签的时候,会触发这个方法。namespaceURI就是命名空间,localName是不带命名空间前缀的标签名,qName是带命名空 间前缀的标签名。通过atts可以得到所有的属性名和相应的值。要注意的是SAX中一个重要的特点就是它的流式处理,当遇到一个标签的时候,它并不会纪录 下以前所碰到的标签,也就是说,在startElement()方法中,所有你所知道的信息,就是标签的名字和属性,至于标签的嵌套结构,上层标签的名 字,是否有子元属等等其它与结构相关的信息,都是不得而知的,都需要你的程序来完成。这使得SAX在编程处理上没有DOM来得那么方便。
  • endElement(String uri, String localName, String name) 这个方法和上面的方法相对应,在遇到结束标签的时候,调用这个方法。
  • characters(char[] ch, int start, int length) 这个方法用来处理在XML文件中读到的内容,第一个参数用于存放文件的内容,后面两个参数是读到的字符串在这个数组中的起始位置和长度,使用new String(ch,start,length)就可以获取内容。

解析itcast.xml触发的事件为:

读到的标签及内容       触发事件

{文档开始}          startDocument()

<persons>           startElement(, “persons”, null, “{Attributes}”)

“\n\t”              characters(“<persons>…</persons>”, “12”, “2”)

<person>            startElement(, “person”, null, “{Attributes}”)

“\n\t\t”            characters(“<persons>…</persons>”, “31”, “3”)

<name>              startElement(, “name”, null, “{Attributes}”)

“李明”              characters(“<persons>…</persons>”, “40”, “2”)

</name>             endElement(“”, “name”, null)

“\n\t\t”            characters(“<persons>…</persons>”, “50”, “3”)

<age>               startElement(, “age”, null, “{Attributes}”)

“30”                characters(“<persons>…</persons>”, “58”, “2”)

</age>              endElement(“”, “age”, null)

“\n\t”              characters(“<persons>…</persons>”, “67”, “2”)

</person>           endElement(“”, “person”, null)

“\n\t”              characters(“<persons>…</persons>”, “79”, “2”)

<person>            startElement(, “person”, null, “{Attributes}”)

“\n\t\t”            characters(“<persons>…</persons>”, “98”, “3”)

<name>              startElement(, “name”, null, “{Attributes}”)

“李向梅”            characters(“<persons>…</persons>”, “107”, “3”)

</name>             endElement(“”, “name”, null)

“\n\t\t”            characters(“<persons>…</persons>”, “118”, “3”)

<age>               startElement(, “age”, null, “{Attributes}”)

“25”                characters(“<persons>…</persons>”, “126”, “2”)

</age>              endElement(“”, “age”, null)

“\n\t”              characters(“<persons>…</persons>”, “135”, “2”)

</person>           endElement(“”, “person”, null)

“\n”                characters(“<persons>…</persons>”, “147”, “1”)

</persons>          endElement(“”, “persons”, null)

{文档结束}          endDocument()

只要为SAX提供实现ContentHandler接口的类,那么该类就可以得到通知事件(实际上就是SAX调用了该类中的回调方法)。因为ContentHandler是一个接口,在使用的时候可能会有些不方便,因此,SAX还为其制定了一个Helper类:DefaultHandler,它实现了这个接口,但是其所有的方法体都为空,在实现的时候,你只需要继承这个类,然后重载相应的方法即可。使用SAX解析itcast.xml的代码如下:

public static List<Person> readXML(InputStream inStream) {

try {

SAXParserFactory spf = SAXParserFactory.newInstance();

SAXParser saxParser = spf.newSAXParser(); //创建解析器

//设置解析器的相关特性,http://xml.org/sax/features/namespaces = true 表示开启命名空间特性

saxParser.setProperty(“http://xml.org/sax/features/namespaces”,true);

XMLContentHandler handler = new XMLContentHandler();

saxParser.parse(inStream, handler);

inStream.close();

return handler.getPersons();

} catch (Exception e) {

e.printStackTrace();

}

return null;

}

import java.util.ArrayList;

import java.util.List;

import org.xml.sax.Attributes;

import org.xml.sax.SAXException;

import org.xml.sax.helpers.DefaultHandler;

import cn.itcast.xml.domain.Person;

public class XMLContentHandler extends DefaultHandler {

private List<Person> persons = null;

private Person currentPerson;

private String tagName = null;//当前解析的元素标签

public List<Person> getPersons() {

return persons;

}

/*

* 接收文档的开始的通知。

*/

@Override public void startDocument() throws SAXException {

persons = new ArrayList<Person>();

}

/*

* 接收字符数据的通知。

*/

@Override public void characters(char[] ch, int start, int length) throws SAXException {

if(tagName!=null){

String data = new String(ch, start, length);

if(tagName.equals(“name”)){

this.currentPerson.setName(data);

}else if(tagName.equals(“age”)){

this.currentPerson.setAge(Short.parseShort(data));

}

}

}

/*

* 接收元素开始的通知。

* 参数意义如下:

*    namespaceURI:元素的命名空间

*    localName :元素的本地名称(不带前缀)

*    qName :元素的限定名(带前缀)

*    atts :元素的属性集合

*/

@Override public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {

if(localName.equals(“person”)){

currentPerson = new Person();

currentPerson.setId(Integer.parseInt(atts.getValue(“id”)));

}

this.tagName = localName;

}

/*

* 接收文档的结尾的通知。

* 参数意义如下:

*    uri :元素的命名空间

*    localName :元素的本地名称(不带前缀)

*    name :元素的限定名(带前缀)

*

*/

@Override public void endElement(String uri, String localName, String name) throws SAXException {

if(localName.equals(“person”)){

persons.add(currentPerson);

currentPerson = null;

}

this.tagName = null;

}

}

使用DOM读取XML文件

除 了可以使用 SAX解析XML文件,大家也可以使用熟悉的DOM来解析XML文件。 DOM解析XML文件时,会将XML文件的所有内容读取到内存中,然后允许您使用DOM API遍历XML树、检索所需的数据。使用DOM操作XML的代码看起来比较直观,并且,在某些方面比基于SAX的实现更加简单。但是,因为DOM需要将 XML文件的所有内容读取到内存中,所以内存的消耗比较大,特别对于运行Android的移动设备来说,因为设备的资源比较宝贵,所以建议还是采用SAX 来解析XML文件,当然,如果XML文件的内容比较小采用DOM是可行的。

import java.io.InputStream;

import java.util.ArrayList;

import java.util.List;

import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;

import org.w3c.dom.Element;

import org.w3c.dom.Node;

import org.w3c.dom.NodeList;

import cn.itcast.xml.domain.Person;

/**

* 使用Dom解析xml文件

*

*/

public class DomXMLReader {

public static List<Person> readXML(InputStream inStream) {

List<Person> persons = new ArrayList<Person>();

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

try {

DocumentBuilder builder = factory.newDocumentBuilder();

Document dom = builder.parse(inStream);

Element root = dom.getDocumentElement();

NodeList items = root.getElementsByTagName(“person”);//查找所有person节点

for (int i = 0; i < items.getLength(); i++) {

Person person = new Person();

//得到第一个person节点

Element personNode = (Element) items.item(i);

//获取person节点的id属性值

person.setId(new Integer(personNode.getAttribute(“id”)));

//获取person节点下的所有子节点(标签之间的空白节点和name/age元素)

NodeList childsNodes = personNode.getChildNodes();

for (int j = 0; j < childsNodes.getLength(); j++) {

Node node = (Node) childsNodes.item(j); //判断是否为元素类型

if(node.getNodeType() == Node.ELEMENT_NODE){    Element childNode = (Element) node;

//判断是否name元素

if (“name”.equals(childNode.getNodeName())) {

//获取name元素下Text节点,然后从Text节点获取数据

person.setName(childNode.getFirstChild().getNodeValue());

} else if (“age”.equals(childNode.getNodeName())) {

person.setAge(new Short(childNode.getFirstChild().getNodeValue()));

}

}

}

persons.add(person);

}

inStream.close();

} catch (Exception e) {

e.printStackTrace();

}

return persons;

}

使用Pull解析器读取XML文件

除了可以使用 SAX和DOM解析XML文件,大家也可以使用Android内置的Pull解析器解析XML文件。 Pull 解析器的运行方式与 SAX 解析器相似。它提供了类似的事件,如:开始元素和结束元素事件,使用parser.next()可以进入下一个元素并触发相应事件。事件将作为数值代码被 发送,因此可以使用一个switch对感兴趣的事件进行处理。当元素开始解析时,调用parser.nextText()方法可以获取下一个Text类型 元素的值。

Pull解析器的源码及文档下载网址:http://www.xmlpull.org/

import org.xmlpull.v1.XmlPullParser;

import android.util.Xml;

import cn.itcast.xml.domain.Person;

public class PullXMLReader {

public static List<Person> readXML(InputStream inStream) {

XmlPullParser parser = Xml.newPullParser();

try {

parser.setInput(inStream, “UTF-8”);

int eventType = parser.getEventType();

Person currentPerson = null;

List<Person> persons = null;

while (eventType != XmlPullParser.END_DOCUMENT) {

switch (eventType) {

case XmlPullParser.START_DOCUMENT://文档开始事件,可以进行数据初始化处理

persons = new ArrayList<Person>();

break;

case XmlPullParser.START_TAG://开始元素事件

String name = parser.getName();

if (name.equalsIgnoreCase(“person”)) {

currentPerson = new Person();

currentPerson.setId(new Integer(parser.getAttributeValue(null, “id”)));

} else if (currentPerson != null) {

if (name.equalsIgnoreCase(“name”)) {

currentPerson.setName(parser.nextText());// 如果后面是Text元素,即返回它的值

} else if (name.equalsIgnoreCase(“age”)) {

currentPerson.setAge(new Short(parser.nextText()));

}

}

break;

case XmlPullParser.END_TAG://结束元素事件

if (parser.getName().equalsIgnoreCase(“person”) && currentPerson != null) {

persons.add(currentPerson);

currentPerson = null;

}

break;

}

eventType = parser.next();

}

inStream.close();

return persons;

} catch (Exception e) {

e.printStackTrace();

}

return null;

}

}

使用Pull解析器生成XML文件

有些时候,我们需要生成一个XML文件,生成XML文件的方法有很多,如:可以只使用一个StringBuilder组拼XML内容,然后把内容写入到文件中;或者使用DOM API生成XML文件,或者也可以使用pull解析器生成XML文件,这里推荐大家使用Pull解析器。

使用Pull解析器生成一个与itcast.xml文件内容相同的myitcast.xml文件。

public static String writeXML(List<Person> persons, Writer writer){

XmlSerializer serializer = Xml.newSerializer();

try {

serializer.setOutput(writer);

serializer.startDocument(“UTF-8”, true);

//第一个参数为命名空间,如果不使用命名空间,可以设置为null

serializer.startTag(“”, “persons”);

for (Person person : persons){

serializer.startTag(“”, “person”);

serializer.attribute(“”, “id”, person.getId().toString());

serializer.startTag(“”, “name”);

serializer.text(person.getName());

serializer.endTag(“”, “name”);

serializer.startTag(“”, “age”);

serializer.text(person.getAge().toString());

serializer.endTag(“”, “age”);

serializer.endTag(“”, “person”);

}

serializer.endTag(“”, “persons”);

serializer.endDocument();

return writer.toString();

} catch (Exception e) {

e.printStackTrace();

}

return null;

}

使用代码如下(生成XML文件):

File xmlFile = new File(“myitcast.xml”);

FileOutputStream outStream = new FileOutputStream(xmlFile);

OutputStreamWriter outStreamWriter = new OutputStreamWriter(outStream, “UTF-8”);

BufferedWriter writer = new BufferedWriter(outStreamWriter);

writeXML(persons, writer);

writer.flush();

writer.close();

如果只想得到生成的xml内容,可以使用StringWriter:

StringWriter writer = new StringWriter();

writeXML(persons, writer);

String content = writer.toString();

源码下载:http://dl.dbank.com/c0glt5uic5

注:请打开DDMS查看读取结果

[转载]Css技巧: 模块化编码

mikel阅读(1125)

[转载]Css技巧: 模块化编码 – Mr.Think的博客@MrThink.net… – 博客园.

原生Js因JQuery的”write less,do more”变得极简, Html因语义化编码变得简明, 那么, 有没有一种方式让Css也更加的高效精致呢? 当然有, 那便是模块化编码. Css的模块化,我们可以理解成(抑或本身就是)OOP思想, 重用性、灵活性、可扩展性便是它终极的目标, “类”便是它的核心, OOP的多用组合少用继承一样是它的基本原则. Css模块化是一个新颖高效的Css编码方式, 若有接触过YUI Css的朋友肯定对这种方式有所了解. 如何Css模块化, 我想这才是大家真正关心的. 我所理解的Css模块化, 应该从两大块去区分. 第一大块, 从整站全局模块化. 这一点大家并不陌生, 时常用到的reset css便是模块化的一部分, 全局通用的字体样式, 链接样式, 以及通用头部底部及主体容器等等这些我们已经熟知, 另外诸如定义文字排版(如.f12{font-size:12px})、定位(如.tl{text-align:left})、长度高度 (如.w10{width:10px})、边距(如.m10{margin:10px})等页面中会常用到的样式,这一类,我们称之为Css通用原子类 (哈,与类扯上关系了,那就权当成类吧).通用原子类有两个特点: 通用性和原子性, 任何页面都可以随意使用它们, 且他们只表现最基础的样式, 一个通用原子类只设置一个样式,不可再分. 关于整站全局模块化不再详述, 本文后面我会贴出阿当的《Web前端开发修炼之道》一书中常用通用原子类样式. 第二大块, 是从视觉效果上模块化, 在视觉上样式和功能相对独立稳定的部分即可视为模块. 拆分这些模块, 应该尽量遵循一个原则: 模块与模块之间尽量不要包含相同的部分, 若有相同部分就再拆出来独立成一个模块. 下图是我画的一个简易的页面视觉图: Css模块化视觉样例 看到上图, 菜鸟的Css编码一般是为1~4定义四个类名,为他们写各自的样式; 明智一点的写法是为1~4定义四个类名, 用.a .b .c .d{…}方式定义共同样式, 然后再为各自定义不同部分的样式; 但是, 还有一种完美的方式, 那便是模块化. 下面我就以上图为例做个简单的模块化分析. 第一步, 分析整个视觉共用部分. 可以看出,1~4中,标题背景,标题文字,内容文字这三个部分的样式都是相同的, 所以, 我们可以为这个四个区块定义一个类名, 将共同的样式写给这个类名:

01 ...
02 <div class="box">
03 <h2>倒霉松鼠再出山</h2>
04 <p>20世纪福克斯将为卖座动画片《冰河世纪》(Ice Age内地译做《冰川时代》)再次开拍续集...</p>
05 </div>
06 <div class="box">
07 <h2>倒霉松鼠再出山</h2>
08 <p>20世纪福克斯将为卖座动画片《冰河世纪》(Ice Age内地译做《冰川时代》)再次开拍续集...</p>
09 </div>
10 <div class="box">
11 <h2>倒霉松鼠再出山</h2>
12 <p>20世纪福克斯将为卖座动画片《冰河世纪》(Ice Age内地译做《冰川时代》)再次开拍续集...</p>
13 </div>
14 <div class="box">
15 <h2>倒霉松鼠再出山</h2>
16 <p>20世纪福克斯将为卖座动画片《冰河世纪》(Ice Age内地译做《冰川时代》)再次开拍续集...</p>
17 </div>
18 ...
19 </div>

第二步, 分析出不同部分, 并权衡高效使用. 可以看出, 不同部分, 主要是内容背景色和区块宽度两部分. 先说背景色, 背景色有三种, 淡黄(1个), 白色(2个), 灰色(1个), 遵从”模块与模块之间尽量不要包含相同的部分, 若有相同部分就再拆出来独立成一个模块”的原则, 我们要把2个白底的样式提出来, 另两个单独定义, 而根据Css优先原则, 我们可以把白底默认定义到第一步中的box样式中, 另两种背景色可做重定义处理. 再来看看宽度与定位, 2,4宽度等同且都右浮动, 所以, 我们可以把这部分提出来模块化, 而浮动一般可以直接调用通用原子类, 所以, 我们仅仅需要定义一个宽度样式中(若这个宽度在通用原子类中也有就更好了). 如此以来, Html可以这样写:

01 ...
02 <div class="box bg_y">
03 <h2>倒霉松鼠再出山</h2>
04 <p>20世纪福克斯将为卖座动画片《冰河世纪》(Ice Age内地译做《冰川时代》)再次开拍续集...</p>
05 </div>
06 <div class="box fr right_w">
07 <h2>倒霉松鼠再出山</h2>
08 <p>20世纪福克斯将为卖座动画片《冰河世纪》(Ice Age内地译做《冰川时代》)再次开拍续集...</p>
09 </div>
10 <div class="box">
11 <h2>倒霉松鼠再出山</h2>
12 <p>20世纪福克斯将为卖座动画片《冰河世纪》(Ice Age内地译做《冰川时代》)再次开拍续集...</p>
13 </div>
14 <div class="box fr right_w bg_g">
15 <h2>倒霉松鼠再出山</h2>
16 <p>20世纪福克斯将为卖座动画片《冰河世纪》(Ice Age内地译做《冰川时代》)再次开拍续集...</p>
17 </div>
18 ...

或许, 这样的结构对Html页面来说, 会显的有些臃肿, 但Css文件因为重用性的提高而大大的减小了. Css模块化是一个比较实用但也需要去领悟的思想, 实际使用中也需要全面的分析, 过多的模块也会导致维护性的降低, 如同OOP编程一样, 我们也要考虑”公有属性”与”私有属性”. 本文通过一个简单的例子解析了Css模块化的基本思想, 更多关于Css模块化的知识, 可以看YUI Css或者其他网络上的资源. do write, less more…Css也可以做到. 附: 阿当《Web前端开发修炼之道》一书中分享的通用原子类:

001 /*文字排版*/
002 .f12{font-size:12px}
003 .f13{font-size:13px}
004 .f14{font-size:14px}
005 .f16{font-size:16px}
006 .f20{font-size:20px}
007 .fb{font-weight:bold}
008 .fn{font-weight:normal}
009 .t2{text-indent:2em}
010 .lh150{line-height:150%}
011 .lh180{line-height:180%}
012 .lh200{line-height:200%}
013 .unl{text-decoration:underline;}
014 .no_unl{text-decoration:none;}
015 /*定位*/
016 .tl{text-align:left}
017 .tc{text-align:center}
018 .tr{text-align:right}
019 .bc{margin-left:auto;margin-right:auto;}
020 .fl{float:left;display:inline}
021 .fr{float:right;display:inline}
022 .cb{clear:both}
023 .cl{clear:left}
024 .cr{clear:right}
025 .clearfix:after{content:".";display:block;height:0;clear:both;visibility:hidden}
026 .clearfix{display:inline-block}* html .clearfix{height:1%}.clearfix{display:block}
027 .vm{vertical-align:middle}
028 .pr{position:relative}
029 .pa{position:absolute}
030 .abs-right{position:absolute;right:0}
031 .zoom{zoom:1}
032 .hidden{visibility:hidden}
033 .none{display:none}
034 /*长度高度*/
035 .w10{width:10px}
036 .w20{width:20px}
037 .w30{width:30px}
038 .w40{width:40px}
039 .w50{width:50px}
040 .w60{width:60px}
041 .w70{width:70px}
042 .w80{width:80px}
043 .w90{width:90px}
044 .w100{width:100px}
045 .w200{width:200px}
046 .w250{width:250px}
047 .w300{width:300px}
048 .w400{width:400px}
049 .w500{width:500px}
050 .w600{width:600px}
051 .w700{width:700px}
052 .w800{width:800px}
053 .w{width:100%}
054 .h50{height:50px}
055 .h80{height:80px}
056 .h100{height:100px}
057 .h200{height:200px}
058 .h{height:100%}
059 /*边距*/
060 .m10{margin:10px}
061 .m15{margin:15px}
062 .m30{margin:30px}
063 .mt5{margin-top:5px}
064 .mt10{margin-top:10px}
065 .mt15{margin-top:15px}
066 .mt20{margin-top:20px}
067 .mt30{margin-top:30px}
068 .mt50{margin-top:50px}
069 .mt100{margin-top:100px}
070 .mb10{margin-bottom:10px}
071 .mb15{margin-bottom:15px}
072 .mb20{margin-bottom:20px}
073 .mb30{margin-bottom:30px}
074 .mb50{margin-bottom:50px}
075 .mb100{margin-bottom:100px}
076 .ml5{margin-left:5px}
077 .ml10{margin-left:10px}
078 .ml15{margin-left:15px}
079 .ml20{margin-left:20px}
080 .ml30{margin-left:30px}
081 .ml50{margin-left:50px}
082 .ml100{margin-left:100px}
083 .mr5{margin-right:5px}
084 .mr10{margin-right:10px}
085 .mr15{margin-right:15px}
086 .mr20{margin-right:20px}
087 .mr30{margin-right:30px}
088 .mr50{margin-right:50px}
089 .mr100{margin-right:100px}
090 .p10{padding:10px;}
091 .p15{padding:15px;}
092 .p30{padding:30px;}
093 .pt5{padding-top:5px}
094 .pt10{padding-top:10px}
095 .pt15{padding-top:15px}
096 .pt20{padding-top:20px}
097 .pt30{padding-top:30px}
098 .pt50{padding-top:50px}
099 .pb5{padding-bottom:5px}
100 .pb10{padding-bottom:10px}
101 .pb15{padding-bottom:15px}
102 .pb20{padding-bottom:20px}
103 .pb30{padding-bottom:30px}
104 .pb50{padding-bottom:50px}
105 .pb100{padding-bottom:100px}
106 .pl5{padding-left:5px}
107 .pl10{padding-left:10px}
108 .pl15{padding-left:15px}
109 .pl20{padding-left:20px}
110 .pl30{padding-left:30px}
111 .pl50{padding-left:50px}
112 .pl100{padding-left:100px}
113 .pr5{padding-right:5px}
114 .pr10{padding-right:10px}
115 .pr15{padding-right:15px}
116 .pr20{padding-right:20px}
117 .pr30{padding-right:30px}
118 .pr50{padding-right:50px}
119 .pr100{padding-right:100px}

原文发布于Mr.Think的博客: http://mrthink.net/css-tips-oopcoding/, 转载请注明.

[转载]案例实战zencart1.38a支付模块简化Fast and Easy Checkout配置

mikel阅读(1260)

[转载]案例实战zencart1.38a支付模块简化Fast and Easy Checkout配置 – PHP编程最快明白 – 博客园.

案例实战zencart1.38a支付模块简化Fast and Easy Checkout配置

zencart默认的支付功能是三步以上才能进入paypal等支付页面的,非常繁复, 所以,有必要实现一个一页买单(one page checkout)的功能,现在,以我的成功经验,给大家讲一个成功的案例吧,绝对能弄好,如果有看不明白的可以找我,只要看完我的教程,一般是不会有问 题了。

虽然可以修改checkout_shipping的内容实现了one page checkout的功能,但是一般的phper还是无从下手。例如,请看这个支付页面:

这是通过手工修改的zencart的支付模块,实现了one page checkout,但难点是Ajax和一些代码逻辑。

今天,我将在我们的网站www.dm800.eu上使用专门的模块实现这一功能,请先看效果:

以上是做好了的效果,www.dm800.eu我采用的是Fast and Easy Checkout模块,只需改动少数(前台显示css等)代码便可,其实不难。步骤和注意的地方如下:

前提条件:

软件我使用的是zencart 1.38a,Fast and Easy Checkout 1.93,都是免费的,php编辑器用的是Dreamweaver。整个测试通过,如果你的zencart版本不是1.38+,建议你安装前先备份好网站 数据,以防万一,具体请看第一步。

第一步,网站数据和数据库备份,Fast and Easy Checkout会覆盖极个别includes或admin里的文件,比如admin里的order.php等,所以,如果你的网站改过了这些文件,就要 备份后按需求改回来的。数据库则会在configuration和configuration_group增加记录而已。这一步是必要的,必须养成良好的 习惯。

第二步,下载Fast and Easy Checkout 1.93,可以用google搜索:Fast and Easy Checkout 1.93 download,出来第一个就是啦,这是英文的,没有带中文等语言,呆会给大家讲语言包翻译。我用的下载地址是:http://www.numinix.com/fast-and-easy-checkout-for-zen-cart,点download now即可,不用放在购物车里面的。

第三步,解压缩Fast and Easy Checkout,对着required_files文件夹,查找所有叫YOUR_TEMPLATE,全部重命名为你的网站里对应的一个TEMPLATE 名字,并且把required_files里的admin文件夹重命名为对应的你的管理文件夹名字。这一步用于最后覆盖用。

第四步,把includes\languages\english复制成你的语言目录名称,对应你网站的这个目录的几个语言,里面的php文件的 define都要一一翻译过来,否则会只看到英文的,小技巧:这里的对应语言的TEMPLATE目录下login.php、logoff.php你的网站 对应的上一级目录是有的,你可以参考一下,只要复制一份再把多出来的定义加上去就行。

第五步,进phpmyadmin,把install.SQL里的内容复制了在zencart数据库上的SQL上运行一次,这时 候,configuration约增加了23条记录和configuration_group增加了一条记录。当然,你也可以复制 install.sql 到 ADMIN->TOOLS->INSTALL SQL(也就是SQL运行器中进行运行)。这时候,管理后台的configuration菜单最后出现了Fast and Easy Checkout configuration,进去把第一个选项Fast and Easy Checkout改为true即可。你也可以改一下跳转到paypal时的字Checkout Confirmation Alternate Text,其他选项不需要改,数据库和后台配置成功。

第六步,现在把required_files里的文件全部覆盖到网站的主目录,打开你的网站,新的支付页面是否大体出来了?现在,美化一下页面的CSS等,如下:

进入required_files\includes\templates\(YOUR_TEMPLATE)目录,打开template里的tpl_checkout_default.php文件,找到这一行:

<?php include(DIR_WS_TEMPLATE . ‘templates/tpl_checkout_stacked.php’); ?>

可以知道checkout的显示是另一个文件控制的。

打开tpl_checkout_stacked.php开始编辑,因为默认的页面显示顺序是先显示运输方式和支付方式的,不符合我们的习惯,我们要 把显示顺序改一改,现在把<!–BOF SHIPPING–>前面的代码全部剪切到<fieldset class=”checkout” id=”checkoutComments”>这一行前面。现在看看效果如何吧。

然后,打开CSS\checkout.css,我们可能要在最后增加些修改的显示样式,比如把id为checkoutShipto的宽度改为80%,把class为checkoutAddress的边框改为无,把class为gvBal的input框的文字上下对齐方式改为top,以及把class为cartTableHeading的背景颜色改为#dedede等。还有一些边距也需要调小一些,具体要和你的模板搭配好。现在刷新再看看效果吧。

第七步,由于www.dm800.eu是免运费的,每次要点击free shipping的checkbox,现在我要不这个按钮默认是选上的,所以在tpl_checkout_stacked.php代码最后增加以下代码:

1 <?php 2  //code:free shipping checked,power by www.dm800.eu 3  if($_SESSION['shipping']==null){ ?> 4  <script type="text/javascript" language="javascript"><!--// 5 updateForm(); 6 //--></script> 7 <?php }

这几行代码是如果shipping没记录则使用JQuery初始化,调用updateForm()函数刷新,这时候加载的运输方式默认都会选上的。

第八步,把原来网站上includes\modules\order_total\ot_coupon.php,找到这一行:

$ratioTax = $adjustedTax/$order->info[‘tax’];

改为:

1 //$ratioTax = $adjustedTax/$order->info['tax']; 2 $ratioTax = (isset($order->info['tax']) && $order->info['tax'] != 0) ? $adjustedTax/$order->info['tax'] : 0;

这是zencart1.38+一个bug,第二行代码我是从1.39h复制过来的,优惠码加上去后报错是因为在后台没定义tax时,会有如下报错:

Warning: Division by zero in 。。。/public_html/includes/modules/order_total/ot_coupon.php on line 364

这时候,我们的Fast and Easy Checkout配置完毕。

其实,整个过程看上去很难,其实,做起来还是比较简单的,也就是小小的错误修复一下,Fast and Easy Checkout采用JQuery来刷新修改自己的地址,这是比较好的地方,还有其他功能比如Checkout Without Account  充许用户不注册购买等,适合做不同的网站需求。

[原创]Type.InvokeMember执行指定参数名方法问题

mikel阅读(1235)

Type.InvokeMember执行方法时候需要按参数名对应参数值时,指定了参数名和参数值,结果传递给方法的参数值和参数名不对应,这个问题很奇怪,调用时调换了参数名和值的顺序就可以,一直不知道为什么?

调用代码:

static void Main(string[] args)
{
Comp comp = new Comp();
Dictionary<String, object> param = new Dictionary<string, object>();
param.Add(“compclass”, “compclass”);
param.Add(“compmodule”, “compmodule”);

param.Add(“compid”, “compid”);

ReflectionHelper.InvokeMethod(comp,”saveinfo”,param.Values.ToArray<Object>(),param.Keys.ToArray<String>());
Console.Read();
}

方法代码:

public ViewData SaveInfo(string compid,string compclass,string compmodule)
{
try{ //传入的compid=”compmodule” compclass=”compid” compmodule=”compclass”

return ExecuteAction(compid, “AlterInfo”);
}catch(Exception e)
{
throw e;
}
}

调换了参数顺序后,则正常运行,调换后的代码:

static void Main(string[] args)
{
Comp comp = new Comp();
Dictionary<String, object> param = new Dictionary<string, object>();
param.Add(“compclass”, “compclass”);

param.Add(“compid”, “compid”);

param.Add(“compmodule”, “compmodule”);

//param.Add(“compcontent”, “compcontent”);

ReflectionHelper.InvokeMethod(comp,”saveinfo”,param.Values.ToArray<Object>(),param.Keys.ToArray<String>());
Console.Read();
}

最终无奈了,解决办法就是,读取Method的参数数组,然后按顺序取值存入Object[]数组中,反射执行方法,代码如下:

String methodName = GetMethodName(context).ToLower();//获得方法名
MethodInfo[] methods = ReflectionHelper.GetMethods(comp);

MethodInfo method = methods.Where<MethodInfo>(m => m.Name.ToLower().Equals(methodName)).ToList<MethodInfo>()[0];
//按参数顺序取参数值
Object[] values = new Object[] { };
Array.Resize<Object>(ref values, method.GetParameters().Length);
foreach (ParameterInfo info in method.GetParameters())
{
values[info.Position]=namedParameters[info.Name];
}

ViewData viewData = method.Invoke(comp, values) as ViewData;

[转载]flex 联机游戏开发 - 斗地主游戏:(一)核心逻辑

mikel阅读(1103)

[转载]flex 联机游戏开发 – 斗地主游戏:(一)核心逻辑 – 博弈居 – 开放的第三方应用游戏开发测试平台 – 博客园.

这是我希望开发的第一个纸牌类游戏,斗地主本身来说是一个有限用户的回合制游戏,核心逻辑与棋类游戏并无多大的不同,但是因为并无多大的行棋算法, 所以位置显得不那么的重要。所以我决定还是用开发四国军棋形成的flexchessapi来开发这个游戏,如果flexchessapi不能胜任这个工 作,我会考虑形成一个通用的flexcardapi来开发这个游戏。这样,我就能利用flexcardapi开发更多的游戏,比如诈金花等。

核心逻辑开发完成后效果如图所示

好了,现在我们开始设计一些纸牌类的一般