﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-大话人生-随笔分类-开发</title><link>http://www.cnitblog.com/stomic/category/7072.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 02 Feb 2016 04:10:13 GMT</lastBuildDate><pubDate>Tue, 02 Feb 2016 04:10:13 GMT</pubDate><ttl>60</ttl><item><title>（转）JAVA事务的概念</title><link>http://www.cnitblog.com/stomic/archive/2016/02/01/90365.html</link><dc:creator>大话人生</dc:creator><author>大话人生</author><pubDate>Mon, 01 Feb 2016 09:51:00 GMT</pubDate><guid>http://www.cnitblog.com/stomic/archive/2016/02/01/90365.html</guid><wfw:comment>http://www.cnitblog.com/stomic/comments/90365.html</wfw:comment><comments>http://www.cnitblog.com/stomic/archive/2016/02/01/90365.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/stomic/comments/commentRss/90365.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/stomic/services/trackbacks/90365.html</trackback:ping><description><![CDATA[<div id="cnblogs_post_body" style="margin-bottom: 20px; word-break: break-word; font-family: Tahoma, Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19.5px;"><p style="margin: 10px auto;">一、什么是事务</p><div>　　事务是访问数据库的一个操作序列，数据库应用系统通过事务集来完成对数据库的存取。事务的正确执行使得数据库从一种状态转换成另一种状态。</div><div>&nbsp;</div><div>　　事务必须服从ISO/IEC所制定的ACID原则。ACID是原子性（atomicity）、一致性（consistency）、隔离性（isolation）和持久性（durability）的缩写事务必须服从ISO/IEC所制定的ACID原则。ACID是原子性（atomicity）、一致性（consistency）、隔离性（isolation）和持久性（durability）的缩写。</div><ul style="margin-left: 30px; padding-left: 0px;"><li style="list-style-type: disc;"><div>&nbsp;<strong>原子性</strong>。即不可分割性，事务要么全部被执行，要么就全部不被执行。如果事务的所有子事务全部提交成功，则所有的数据库操作被提交，数据库状态发生转换；如果有子事务失败，则其他子事务的数据库操作被回滚，即数据库回到事务执行前的状态，不会发生状态转换。</div></li></ul><ul style="margin-left: 30px; padding-left: 0px;"><li style="list-style-type: disc;"><div>&nbsp;<strong>一致性或可串性</strong>。事务的执行使得数据库从一种正确状态转换成另一种正确状态。</div></li></ul><ul style="margin-left: 30px; padding-left: 0px;"><li style="list-style-type: disc;"><div><strong>隔离性</strong>。在事务正确提交之前，不允许把该事务对数据的任何改变提供给任何其他事务，即在事务正确提交之前，它可能的结果不应显示给任何其他事务。</div></li></ul><ul style="margin-left: 30px; padding-left: 0px;"><li style="list-style-type: disc;"><div><strong>持久性</strong>。事务正确提交后，其结果将永久保存在数据库中，即使在事务提交后有了其他故障，事务的处理结果也会得到保存。 　　</div></li></ul><p style="margin: 10px auto;">　　运行嵌入式SQL应用程序或脚本，在可执行SQL语句第一次执行时(在建立与数据库的连接之后或在现有事务终止之后)，事务就会自动启动。在启动事务之后，必须由启动事务的用户或应用程序显式地终止它，除非使用了称为自动提交(automatic commit)的过程(在这种情况下，发出的每个单独的SQL语句被看做单个事务，它一执行就被隐式地提交了)。</p><p style="margin: 10px auto;">　　在大多数情况下，通过执行COMMIT或ROLLBACK语句来终止事务。当执行COMMIT语句时，自从事务启动以来对数据库所做的一切更改就成为永久性的了-- 即它们被写到磁盘。当执行ROLLBACK语句时，自从事务启动以来对数据库所做的一切更改都被撤销，并且数据库返回到事务开始之前所处的状态。不管是哪种情况，数据库在事务完成时都保证能回到一致状态。</p><p style="margin: 10px auto;">　　一定要注意一点：虽然事务通过确保对数据的更改仅在事务被成功提交之后才成为永久性的，从而提供了一般的数据库一致性，但还是须要用户或应用程序来确保每个事务中执行的SQL操作序列始终会导致一致的数据库。</p><p style="margin: 10px auto;"></p><p style="margin: 10px auto;">二、数据库系统支持两种事务模式：</p><ul style="margin-left: 30px; padding-left: 0px;"><li style="list-style-type: disc;"><strong>自动提交模式：</strong>每个SQL语句都是一个独立的事务，当数据库系统执行完一个SQL语句后，会自动提交事务。</li><strong>﻿</strong><li style="list-style-type: disc;"><strong>手动提交模式：</strong>必须由数据库客户程序显示指定事务开始边界和结束边界。</li></ul><p style="margin: 10px auto;">　　注：MySQL中数据库表分为3种类型：INNODB、BDB和MyISAM，其中MyISAM不支持数据库事务。MySQL中create table 语句默认为MyISAM类型。</p><p style="margin: 10px auto;">　　</p><p style="margin: 10px auto;">三、对于同时运行的多个事务，当这些事务访问数据库中相同的数据时，如果没有采取必要的隔离机制，就会导致各种并发问题，这些并发问题可归纳为以下几类：</p><ul style="margin-left: 30px; padding-left: 0px;"><li style="list-style-type: disc;"><strong>第一类丢失更新：</strong>撤销一个事务时，把其他事务已提交的更新数据覆盖。　</li><li style="list-style-type: disc;"><strong>脏读：</strong>一个事务读到另一个事务为提交的更新数据。</li><li style="list-style-type: disc;"><strong>虚读：</strong>一个事务读到另一个事务已提交的新插入的数据。</li><li style="list-style-type: disc;"><strong>不可重复读：</strong>一个事务读到另一个事务已提交的更新数据。</li><li style="list-style-type: disc;"><strong>第二类丢失更新：</strong>这是不可重复读中的特例，一个事务覆盖另一个事务已提交的更新数据。　　</li></ul><p style="margin: 10px auto;">　</p><ul style="margin-left: 30px; padding-left: 0px;"></ul><p style="margin: 10px auto;">四、隔离级别</p><p style="margin: 10px auto;"></p><p style="margin: 10px auto;"></p><p style="margin: 10px auto;"></p><p style="margin: 10px auto;">　　当数据库系统采用read Commited隔离级别时，会导致不可重复读喝第二类丢失更新的并发问题，可以在应用程序中采用悲观锁或乐观锁来避免这类问题。从应用程序的角度，锁可以分为以下几类：</p><ul style="margin-left: 30px; padding-left: 0px;"><li style="list-style-type: disc;"><strong>Serializable(串行化)：</strong>一个事务在执行过程中完全看不到其他事务对数据库所做的更新。</li><li style="list-style-type: disc;"><strong>Repeatable Read(可重复读)：</strong>一个事务在执行过程中可以看到其他事务已经提交的新插入的记录，但是不能看到其他事务对已有记录的更新。</li><li style="list-style-type: disc;"><strong>Read Commited（读已提交数据）：</strong>一个事务在执行过程中可以看到其他事务已经提交的新插入的记录，而且能看到其他事务已经提交的对已有记录的更新</li><li style="list-style-type: disc;"><strong>Read Uncomitted（读未提交数据）：</strong>一个事务在执行过程中可以拷打其他事务没有提交的新插入的记录，而且能看到其他事务没有提交的对已有记录的更新。</li></ul><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp; 隔离级别越高，越能保证数据的完整性和一致性，但是对并发性能的影响也越大。对于多数应用程序，可以有优先考虑把数据库系统的隔离级别设为Read Commited，它能够避免脏读，而且具有较好的并发性能。尽管它会导致不可重复读、虚读和第二类丢失更新这些并发问题，在可能出现这类问题的个别场合，可以由应用程序采用悲观锁或乐观锁来控制。</p><p style="margin: 10px auto;">　　当数据库系统采用read Commited隔离级别时，会导致不可重复读喝第二类丢失更新的并发问题，可以在应用程序中采用悲观锁或乐观锁来避免这类问题。从应用程序的角度，锁可以分为以下几类：</p><p style="margin: 10px auto;">　　<strong>A.悲观锁</strong>：指在应用程序中显示的为数据资源加锁。尽管能防止丢失更新和不可重复读这类并发问题，但是它会影响并发性能，因此应该谨慎地使用。&nbsp;<br /><br />　　<strong>B.乐观锁</strong>：乐观锁假定当前事务操作数据资源时，不回有其他事务同时访问该数据资源，因此完全依靠数据库的隔离级别来自动管理锁的工作。应用程序采用版本控制手段来避免可能出现的并发问题。<br /><br /></p><p style="margin: 10px auto;">五、悲观锁有两种实现方式。</p><p style="margin: 10px auto;">　　A.在应用程序中显示指定采用数据库系统的独占所来锁定数据资源。SQL语句：select ... for update，在Hibernate中使用get，load时如session.get(Account.class,new Long(1),LockMode,UPGRADE)&nbsp;<br /><br />　　B.在数据库表中增加一个表明记录状态的LOCK字段，当它取值为&#8220;Y&#8221;时，表示该记录已经被某个事务锁定，如果为&#8220;N&#8221;，表明该记录处于空闲状态，事务可以访问它。增加锁标记字段就可以实现。</p><p style="margin: 10px auto;">　　利用Hibernate的版本控制来实现乐观锁</p><p style="margin: 10px auto;">　　乐观锁是由程序提供的一种机制，这种机制既能保证多个事务并发访问数据，又能防止第二类丢失更新问题。</p><p style="margin: 10px auto;">　　在应用程序中可以利用Hibernate提供的版本控制功能来视线乐观锁，OR映射文件中的&lt;version&gt;元素和&lt;timestamp&gt;都具有版本控制的功能，一般推荐采用&lt;version&gt;</p></div><div id="MySignature" style="font-family: Tahoma, Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19.5px;">当一个人找不到出路的时候，最好的办法就是将当前能做好的事情做到极致，做到无人能及。</div><img src ="http://www.cnitblog.com/stomic/aggbug/90365.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/stomic/" target="_blank">大话人生</a> 2016-02-01 17:51 <a href="http://www.cnitblog.com/stomic/archive/2016/02/01/90365.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>（转）Servlet调用流程</title><link>http://www.cnitblog.com/stomic/archive/2016/01/04/90334.html</link><dc:creator>大话人生</dc:creator><author>大话人生</author><pubDate>Mon, 04 Jan 2016 08:14:00 GMT</pubDate><guid>http://www.cnitblog.com/stomic/archive/2016/01/04/90334.html</guid><wfw:comment>http://www.cnitblog.com/stomic/comments/90334.html</wfw:comment><comments>http://www.cnitblog.com/stomic/archive/2016/01/04/90334.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/stomic/comments/commentRss/90334.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/stomic/services/trackbacks/90334.html</trackback:ping><description><![CDATA[<div id="article_content" class="article_content">
<p><span style="font-size:14px">首先说说我们的<strong>Tomcat7.0的目录结构</strong>：</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 包括目录：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bin </span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conf</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lib</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logs</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;webapps</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; work</span></p>
<p><span style="font-size:14px">&nbsp;</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bin文件：</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 存放各种平台下启动和关闭Tomcat的脚本文件。</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;startup.bat是windows下启动tomcat的文件。</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;shutdown.bat是关闭tomcat的文件。</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; conf目录：</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Tomcat的各种配置文件，tomcat启动时需要读取的配置文件：server.xml</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lib目录：</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 存放Tomcat所需的各种jar文件。</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logs目录：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 存放Tomcat的日志文件。</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp目录：</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 临时文件目录，用于存放Tomcat运行时的临时文件。</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; webapps目录：</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;web应用的发布目录，把java编写的web应用或打包成的war格式的web应用文件放入该目录下，就能通过Tomcat服务器访问了。</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;work目录：</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Tomcat把JSP文件编译生成Servlet文件存放在这个目录下。</span></p>
<p><span style="font-size:14px">&nbsp;</span></p>
<p><span style="font-size:14px">数据传送流程：</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <img alt="" src="http://img.blog.csdn.net/20130527165449283" /></span></p>
<p><span style="font-size:14px">&nbsp;&nbsp; </span></p>
<p><span style="font-size:14px"><strong>java servlet</strong>：</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 我们要在webapps目录下建立一个我们javaweb项目的目录结构test_servlet：</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WEB-INF/classes web.xml lib&nbsp; </span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lib文件：存放java包，数据库驱动程序等等。</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; classes文件：存放已编译好的类。</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Web.Xml：配置一些信息，例如Servlet的配置，名字，路径等，告诉我们的Tomcat我们使用的哪个Servlet。</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 我们依次来写：</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; servlet代码：</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
<div class="dp-highlighter bg_java"><div class="bar" style="display: block;"><div class="tools"><strong>[java]</strong> <a href="#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><a href="#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="#" class="About" title="?" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a><div style="position: absolute; left: 465px; top: 2369px; width: 27px; height: 15px; z-index: 99;"><embed id="ZeroClipboardMovie_1" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="27" height="15" name="ZeroClipboardMovie_1" align="center" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=1&amp;width=27&amp;height=15" wmode="transparent"></div></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>&lt;span&nbsp;style=</span><span class="string">"font-size:14px;"</span><span>&gt;</span><span class="comment">//引入java的包。</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="keyword">import</span><span>&nbsp;javax.servlet.http.*;&nbsp;&nbsp;</span></span></li><li class="alt"><span><span class="keyword">import</span><span>&nbsp;java.io.*;&nbsp;&nbsp;</span></span></li><li class=""><span><span class="keyword">import</span><span>&nbsp;javax.servlet.*;&nbsp;&nbsp;</span></span></li><li class="alt"><span><span class="comment">//第一个Servlet程序。</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;LoginServlet&nbsp;</span><span class="keyword">extends</span><span>&nbsp;HttpServlet&nbsp;&nbsp;</span></span></li><li class="alt"><span>{&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//指定调用哪个servlet。</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//get提交和post提交两种方式。</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;doGet(HttpServletRequest&nbsp;request,HttpServletResponse&nbsp;response)&nbsp;</span><span class="keyword">throws</span><span>&nbsp;ServletException,IOException&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//取得客户端的数据。</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;username&nbsp;=&nbsp;request.getParameter(<span class="string">"username"</span><span>);&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;password&nbsp;=&nbsp;request.getParameter(<span class="string">"password"</span><span>);&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(<span class="string">"username"</span><span>&nbsp;+&nbsp;username);&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(<span class="string">"password"</span><span>&nbsp;+&nbsp;password);&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//向浏览器上写数据。可以有流。字符流。</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//setContext设置响应的内容类型。设置为html类型或者中文。</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;response.setContentType(<span class="string">"text/html;charset=GB18030"</span><span>);&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//response.getWriter().println("Login&nbsp;Success!!!");</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//response.getWriter().println("登录成功!!!");</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;response.getWriter().println(<span class="string">"&lt;html&gt;"</span><span>);&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;response.getWriter().println(<span class="string">"&lt;head&gt;"</span><span>);&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;response.getWriter().println(<span class="string">"&lt;title&gt;登录信息&lt;/title&gt;"</span><span>);&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;response.getWriter().println(<span class="string">"&lt;/head&gt;"</span><span>);&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;response.getWriter().println(<span class="string">"&lt;body&gt;"</span><span>);&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;response.getWriter().println(<span class="string">"欢迎【"</span><span>&nbsp;+&nbsp;username&nbsp;+&nbsp;</span><span class="string">"】登录成功！！！"</span><span>);&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;response.getWriter().println(<span class="string">"&lt;/body&gt;"</span><span>);&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;response.getWriter().println(<span class="string">"&lt;/html&gt;"</span><span>);&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//采用post的提交方式。</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;doPost(HttpServletRequest&nbsp;request,HttpServletResponse&nbsp;response)&nbsp;</span><span class="keyword">throws</span><span>&nbsp;ServletException,IOException&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;doGet(request,response);&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt"><span>}&lt;/span&gt;&nbsp;&nbsp;</span></li></ol></div><pre class="java" name="code" style="display: none;"><span style="font-size:14px;">//引入java的包。
import javax.servlet.http.*;
import java.io.*;
import javax.servlet.*;
//第一个Servlet程序。
public class LoginServlet extends HttpServlet
{
//指定调用哪个servlet。
//get提交和post提交两种方式。
public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException
{
//取得客户端的数据。
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println("username" + username);
System.out.println("password" + password);
//向浏览器上写数据。可以有流。字符流。
//setContext设置响应的内容类型。设置为html类型或者中文。
response.setContentType("text/html;charset=GB18030");
//response.getWriter().println("Login Success!!!");
//response.getWriter().println("登录成功!!!");
response.getWriter().println("&lt;html&gt;");
response.getWriter().println("&lt;head&gt;");
response.getWriter().println("&lt;title&gt;登录信息&lt;/title&gt;");
response.getWriter().println("&lt;/head&gt;");
response.getWriter().println("&lt;body&gt;");
response.getWriter().println("欢迎【" + username + "】登录成功！！！");
response.getWriter().println("&lt;/body&gt;");
response.getWriter().println("&lt;/html&gt;");
}
//采用post的提交方式。
public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException
{
doGet(request,response);
}
}</span></pre>
<p><br />
<span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 虽然我们引入了jar包，但是程序是否能从找到tomcat的servlet&nbsp; jar包，我们需要配置一下用户的环境变量，把lib\servlet-api.jar包配置到classpath变量。当然tomcat也是java编码的，所以我们也配置一下JAVA_HOME变量，可以在tomcat的批处理命令startup.bat中进行配置，set JAVA_HOME=C:\Program Files\Java\jdk1.6.0_43。</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 然后把这个java文件编译成.class 文件，放到classes文件夹中。</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; html代码：</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
<div class="dp-highlighter bg_html"><div class="bar" style="display: block;"><div class="tools"><strong>[html]</strong> <a href="#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><a href="#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="#" class="About" title="?" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a><div style="position: absolute; left: 467px; top: 3219px; width: 27px; height: 15px; z-index: 99;"><embed id="ZeroClipboardMovie_2" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="27" height="15" name="ZeroClipboardMovie_2" align="center" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=2&amp;width=27&amp;height=15" wmode="transparent"></div></div></div><ol start="1" class="dp-xml"><li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">span</span><span>&nbsp;</span><span class="attribute">style</span><span>=</span><span class="attribute-value">"font-size:14px;"</span><span class="tag">&gt;</span><span class="tag">&lt;</span><span class="tag-name">html</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">head</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">title</span><span class="tag">&gt;</span><span>登录</span><span class="tag">&lt;/</span><span class="tag-name">title</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">head</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">body</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comments">&lt;!--这是绝对路径--&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comments">&lt;!--相对路径写法:action="LoginServlet"--&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">form</span><span>&nbsp;</span><span class="attribute">action</span><span>=</span><span class="attribute-value">"http://127.0.0.1:8080/test_servlet/LoginServlet"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;用户：<span class="tag">&lt;</span><span class="tag-name">input</span><span>&nbsp;</span><span class="attribute">type</span><span>=</span><span class="attribute-value">"text"</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"username"</span><span class="tag">&gt;</span><span class="tag">&lt;</span><span class="tag-name">br</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;密码：<span class="tag">&lt;</span><span class="tag-name">input</span><span>&nbsp;</span><span class="attribute">type</span><span>=</span><span class="attribute-value">"password"</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"password"</span><span class="tag">&gt;</span><span class="tag">&lt;</span><span class="tag-name">br</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">input</span><span>&nbsp;</span><span class="attribute">type</span><span>=</span><span class="attribute-value">"submit"</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">"登录"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">form</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">body</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="tag">&lt;/</span><span class="tag-name">html</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">span</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li></ol></div><pre class="html" name="code" style="display: none;"><span style="font-size:14px;">&lt;html&gt;
&lt;head&gt;
&lt;title&gt;登录&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;!--这是绝对路径--&gt;
&lt;!--相对路径写法:action="LoginServlet"--&gt;
&lt;form action="http://127.0.0.1:8080/test_servlet/LoginServlet"&gt;
用户：&lt;input type="text" name="username"&gt;&lt;br&gt;
密码：&lt;input type="password" name="password"&gt;&lt;br&gt;
&lt;input type="submit" value="登录"&gt;
&lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;</span></pre>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Web.Xml :</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
<div class="dp-highlighter bg_html"><div class="bar" style="display: block;"><div class="tools"><strong>[html]</strong> <a href="#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><a href="#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="#" class="About" title="?" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a><div style="position: absolute; left: 467px; top: 3543px; width: 27px; height: 15px; z-index: 99;"><embed id="ZeroClipboardMovie_3" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="27" height="15" name="ZeroClipboardMovie_3" align="center" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=3&amp;width=27&amp;height=15" wmode="transparent"></div></div></div><ol start="1" class="dp-xml"><li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">span</span><span>&nbsp;</span><span class="attribute">style</span><span>=</span><span class="attribute-value">"font-size:14px;"</span><span class="tag">&gt;</span><span class="tag">&lt;?</span><span class="tag-name">xml</span><span>&nbsp;</span><span class="attribute">version</span><span>=</span><span class="attribute-value">"1.0"</span><span>&nbsp;</span><span class="attribute">encoding</span><span>=</span><span class="attribute-value">"ISO-8859-1"</span><span class="tag">?&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;</span></li><li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">web-app</span><span>&nbsp;</span><span class="attribute">xmlns</span><span>=</span><span class="attribute-value">"http://java.sun.com/xml/ns/javaee"</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;<span class="attribute">xmlns:xsi</span><span>=</span><span class="attribute-value">"http://www.w3.org/2001/XMLSchema-instance"</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;<span class="attribute">xsi:schemaLocation</span><span>="http://java.sun.com/xml/ns/javaee&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;<span class="attribute">version</span><span>=</span><span class="attribute-value">"3.0"</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;<span class="attribute">metadata-complete</span><span>=</span><span class="attribute-value">"true"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">servlet</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">servlet-name</span><span class="tag">&gt;</span><span>MyServlet</span><span class="tag">&lt;/</span><span class="tag-name">servlet-name</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">servlet-class</span><span class="tag">&gt;</span><span>LoginServlet</span><span class="tag">&lt;/</span><span class="tag-name">servlet-class</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">servlet</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">servlet-mapping</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">servlet-name</span><span class="tag">&gt;</span><span>MyServlet</span><span class="tag">&lt;/</span><span class="tag-name">servlet-name</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">url-pattern</span><span class="tag">&gt;</span><span>/LoginServlet</span><span class="tag">&lt;/</span><span class="tag-name">url-pattern</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">servlet-mapping</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span><span class="tag">&lt;/</span><span class="tag-name">web-app</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">span</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li></ol></div><pre class="html" name="code" style="display: none;"><span style="font-size:14px;">&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;
&lt;web-app xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                      http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
  version="3.0"
  metadata-complete="true"&gt;
    &lt;servlet&gt;
&lt;servlet-name&gt;MyServlet&lt;/servlet-name&gt;
&lt;servlet-class&gt;LoginServlet&lt;/servlet-class&gt;
&lt;/servlet&gt;
&lt;servlet-mapping&gt;
&lt;servlet-name&gt;MyServlet&lt;/servlet-name&gt;
&lt;url-pattern&gt;/LoginServlet&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;
&lt;/web-app&gt;</span></pre>
<p><br />
<span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 启动Tomcat就可以执行成功。</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 下面是servlet的调用过程,也可以用HTTPLook软件来跟踪：</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <img alt="" src="http://img.blog.csdn.net/20130527165907754" /></span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <img src="http://img.blog.csdn.net/20130527173727374" alt="" /></span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;作为一个java的初学者来说，开始一个servlet让我很模糊，什么是servlet呢？有道上说是servlet（小服务程序），学过了发现，也是26个英文字母的组合，其实说白了就是java代码，但是因为他的用途，人们给他抽象总结了一个层次，叫做servlet，。就相当于县长首先是人，再是县长~，貌似搞得这儿复杂~不也是个干活的么~</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 同样是网页，.net开发的网页和java开发的有什么区别呢？.net中有没有servlet？据说.cs文件写&#8220;servlet&#8221;就相当于servlet了。呵呵，有待更深的研究，加油！</span></p>
<p><span style="font-size:14px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size:18px"></span></p>
</div>
<img src ="http://www.cnitblog.com/stomic/aggbug/90334.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/stomic/" target="_blank">大话人生</a> 2016-01-04 16:14 <a href="http://www.cnitblog.com/stomic/archive/2016/01/04/90334.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【转+分析】JAVA: 为什么要使用"抽象类"? 使用"抽象类"有什么好处?</title><link>http://www.cnitblog.com/stomic/archive/2015/11/04/90273.html</link><dc:creator>大话人生</dc:creator><author>大话人生</author><pubDate>Wed, 04 Nov 2015 07:04:00 GMT</pubDate><guid>http://www.cnitblog.com/stomic/archive/2015/11/04/90273.html</guid><wfw:comment>http://www.cnitblog.com/stomic/comments/90273.html</wfw:comment><comments>http://www.cnitblog.com/stomic/archive/2015/11/04/90273.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/stomic/comments/commentRss/90273.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/stomic/services/trackbacks/90273.html</trackback:ping><description><![CDATA[<pre class="reply-text mb10" id="best-answer-content" name="code">问你个问题，你知道什么是&#8220;东西&#8221;吗？什么是&#8220;物体&#8221;吗？ 
&#8220;麻烦你，小王。帮我把那个东西拿过来好吗&#8221; 
在生活中，你肯定用过这个词－－东西。 
小王：&#8220;你要让我帮你拿那个水杯吗？&#8221; 
你要的是水杯类的对象。而东西是水杯的父类。通常东西类没有实例对象，但我们有时需要东西的引用指向它的子类实例。 
你看你的房间乱成什么样子了，以后不要把东西乱放了，知道么？ 
又是东西，它是一个数组。而数组中的元素都是其子类的实例。 
--------- 
上面讲的只是子类和父类。而没有说明抽象类的作用。抽象类是据有一个或多个抽象方法的类，必须声明为抽象类。抽象类的特点是，不能创建实例。 
这些该死的抽象类，也不知道它有什么屁用。我非要把它改一改不可。把抽象类中的抽象方法都改为空实现。也就是给抽象方法加上一个方法体，不过这个方法体是空的。这回抽象类就没有抽象方法了。它就可以不在抽象了。 
当你这么尝试之后，你发现，原来的代码没有任何变化。大家都还是和原来一样，工作的很好。你这回可能更加相信，抽象类根本就没有什么用。但总是不死心，它应该有点用吧，不然创造Java的这伙传说中的天才不成了傻子了吗？ 
接下来，我们来写一个小游戏。俄罗斯方块！我们来分析一下它需要什么类？
我知道它要在一个矩形的房子里完成。这个房子的上面出现一个方块，慢慢的下落，当它接触到地面或是其它方块的尸体时，它就停止下落了。然后房子的上面又会出现一个新的方块，与前一个方块一样，也会慢慢的下落。在它还没有死亡之前，我可以尽量的移动和翻转它。这样可以使它起到落地时起到一定的作用，如果好的话，还可以减下少几行呢。这看起来好象人生一样，它在为后来人努力着。
当然，我们不是真的要写一个游戏。所以我们简化它。我抽象出两个必须的类，一个是那个房间，或者就它地图也行。另一个是方块。我发现方块有很多种，数一下，共6种。它们都是四个小矩形构成的。但是它们还有很多不同，例如：它们的翻转方法不同。先把这个问题放到一边去，我们回到房子这个类中。
房子上面总是有方块落下来，房子应该有个属性是方块。当一个方块死掉后，再创建一个方块，让它出现在房子的上面。当玩家要翻转方法时，它翻转的到底是哪个方块呢？当然，房子中只有一个方块可以被翻转，就是当前方块。它是房子的一个属性。那这个属性到底是什么类型的呢？方块有很多不同啊，一共有6种之多，我需要写六个类。一个属性不可能有六种类型吧。当然一个属性只能有一种类型。
我们写一个方块类，用它来派生出6个子类。而房子类的当前方块属性的类型是方块类型。它可以指向任何子类。但是，当我调用当前方块的翻转方法时，它的子类都有吗？如果你把翻转方法写到方块类中，它的子类自然也就有了。可以这六种子类的翻转方法是不同的。我们知道'田'方块，它只有一种状态，无论你怎么翻转它。而长条的方块有两种状态。一种是&#8216;－&#8217;，另一种是&#8216;｜&#8217;。这可怎么办呢？我们知道Java的多态性，你可以让子类来重写父类的方法。也就是说，在父类中定义这个方法，子类在重写这个方法。
那么在父类的这个翻转方法中，我写一些什么代码呢？让它有几种状态呢？因为我们不可能实例化一个方块类的实例，所以它的翻转方法中的代码并不重要。而子类必须去重写它。那么你可以在父类的翻转方法中不写任何代码，也就是空方法。
我们发现，方法类不可能有实例，它的翻转方法的内容可以是任何的代码。而子类必须重写父类的翻转方法。这时，你可以把方块类写成抽象类，而它的抽象方法就是翻转方法。当然，你也可以把方块类写为非抽象的，也可以在方块类的翻转方法中写上几千行的代码。但这样好吗？难道你是微软派来的，非要说Java中的很多东西都是没有用的吗？
<span style="color:#CC0000;">当我看到方块类是抽象的，我会很关心它的抽象方法。我知道它的子类一定会重写它，而且，我会去找到抽象类的引用。它一定会有多态性的体现</span>。
<span style="color:#FF0000;">但是，如果你没有这样做，我会认为可能会在某个地方，你会实例化一个方块类的实例，但我找了所有的地方都没有找到。最后我会大骂你一句，你是来欺骗我的吗，你这个白痴。</span>
把那些和&#8220;东西&#8221;差不多的类写成抽象的。而水杯一样的类就可以不是抽象的了。当然水杯也有几千块钱一个的和几块钱一个的。水杯也有子类，例如，我用的水杯都很高档，大多都是一次性的纸水杯。
记住一点，面向对象不是来自于Java，面向对象就在你的生活中。而Java的面向对象是方便你解决复杂的问题。这不是说面向对象很简单，虽然面向对象很复杂，但Java知道，你很了解面向对象，因为它就在你身边。</pre>
<img src ="http://www.cnitblog.com/stomic/aggbug/90273.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/stomic/" target="_blank">大话人生</a> 2015-11-04 15:04 <a href="http://www.cnitblog.com/stomic/archive/2015/11/04/90273.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(转)Java+PHP整合</title><link>http://www.cnitblog.com/stomic/archive/2015/10/22/90236.html</link><dc:creator>大话人生</dc:creator><author>大话人生</author><pubDate>Thu, 22 Oct 2015 10:18:00 GMT</pubDate><guid>http://www.cnitblog.com/stomic/archive/2015/10/22/90236.html</guid><wfw:comment>http://www.cnitblog.com/stomic/comments/90236.html</wfw:comment><comments>http://www.cnitblog.com/stomic/archive/2015/10/22/90236.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/stomic/comments/commentRss/90236.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/stomic/services/trackbacks/90236.html</trackback:ping><description><![CDATA[<p style="color: #333333; font-size: 14px; padding-top: 0px; padding-bottom: 15px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;">验证两种各自领域称王的语言（JAVA /PHP），不同语言、不同机制的组合在一起<strong><span style="color: #ff0000;">，PHP负责WEB层，Java负责业务和数据逻辑层</span></strong>，真是一对黄金组合（<span style="padding: 0px; margin: 0px;">Java+PHP整合=混血新宠儿</span>），发挥各自优势，适合开发B/S企业程序。</p><p style="color: #333333; font-size: 14px; padding-top: 0px; padding-bottom: 15px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px;"><span style="font-size: 32px; padding: 0px; margin: 0px;"><a name="_Toc296514494" style="color: #336699; padding: 0px; margin: 0px;"><span style="padding: 0px; margin: 0px;"><span style="font-size: 24px; padding: 0px; margin: 0px;">1</span>&nbsp;</span><span style="font-size: 24px; padding: 0px; margin: 0px;">技术问题</span></a></span></span></p><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;">两种不同环境，不同机制的语言结合，首先要解决的是如何通讯？其次是通讯内容如何处理？最后是两者开发，部署环境整合？</div><div style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px;"><span style="font-size: 24px; padding: 0px; margin: 0px;"><a name="_Toc296514495" style="color: #336699; padding: 0px; margin: 0px;"><span style="padding: 0px; margin: 0px;"><span style="font-size: 14px; padding: 0px; margin: 0px;">1.1</span><span style="padding: 0px; margin: 0px;">&nbsp;&nbsp;&nbsp;</span></span><span style="font-size: 14px; padding: 0px; margin: 0px;">两种语言对比</span></a></span></span></div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px;">Php</span>：直观，快速，简单，易学，开发动态网页效率高，草根文化气息浓重，是语言世界的平民英雄，注重于结果。</div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px;">Java</span>：强大而复杂，有众多高端功能，又有IMB、Oracle等企业大颚的追捧，是语言世界的贵族王子。</div><div style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px;"><span style="font-size: 24px; padding: 0px; margin: 0px;"><a name="_Toc296514496" style="color: #336699; padding: 0px; margin: 0px;"><span style="padding: 0px; margin: 0px;"><span style="font-size: 14px; padding: 0px; margin: 0px;">1.2</span><span style="padding: 0px; margin: 0px;">&nbsp;&nbsp;&nbsp;</span></span><span style="font-size: 14px; padding: 0px; margin: 0px;">通讯问题</span></a></span></span></div><div style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px;"><span style="font-size: 18px; padding: 0px; margin: 0px;"><a name="_Toc296514497" style="color: #336699; padding: 0px; margin: 0px;"><span style="padding: 0px; margin: 0px;"><span style="font-size: 14px; padding: 0px; margin: 0px;">1.2.1</span><span style="padding: 0px; margin: 0px;">&nbsp;&nbsp;&nbsp;</span></span><span style="font-size: 14px; padding: 0px; margin: 0px;">消息队列</span></a></span></span></div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;">从操作系统层面观察： PHP和Java是系统中运行的不同进程，他们之间沟通属于进程间通信技术(IPC)：</div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px; font-size: 12pt; line-height: 24px; font-family: Verdana, sans-serif;">&nbsp;<span style="padding: 0px; margin: 0px; font-size: 12pt;">&nbsp;<span style="padding: 0px; margin: 0px; font-size: 12pt;">&nbsp;&nbsp;</span></span></span></div><p style="color: #333333; font-size: 14px; padding-top: 0px; padding-bottom: 15px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><a href="http://img1.51cto.com/attachment/201106/233917104.jpg" target="_blank" style="color: #336699; text-decoration: initial; padding: 0px; margin: 0px;"><span style="color: #000000;"><img alt="" src="http://img1.51cto.com/attachment/201106/233917104.jpg" border="0" style="border: none; max-width: 100%; padding: 0px; margin: 0px; vertical-align: top;" /></span></a></p><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px; font-size: 12pt; line-height: 24px; font-family: Verdana, sans-serif;"></span></div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;">在传统的Unix环境中，IPC技术有：管道、消息队列、共享内存、信号量等，但在同一个系统中，IPC通信比基于TCP的socket通信在性能、资源占用方面有相当大的优势。</div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;">在Unix/Linux中，PHP基本提供了所有IPC的访问接口，因为PHP可以看作是以C语言为核心的一个壳，而IPC是系统内核的组成部分，对外提供了一组C函数接口，因此PHP可以非常顺畅的运用IPC技术。而Java为了追求夸平台性(Windows的IPC技术和Unix的不同)，没有提供系统级的IPC访问，这也体现了Java的文化特色：为追求统一可牺牲效能。</div><div style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px;"><span style="font-size: 18px; padding: 0px; margin: 0px;"><a name="_Toc296514498" style="color: #336699; padding: 0px; margin: 0px;"><span style="padding: 0px; margin: 0px;"><span style="font-size: 14px; padding: 0px; margin: 0px;">1.2.2</span><span style="padding: 0px; margin: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span><span style="font-size: 14px; padding: 0px; margin: 0px;">Socket</span></a></span></span></div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><strong><span style="color: #ff0000;">消息队列技术只能适用于Unix/Linux系统，而SOCKET基于TCP/IP的通讯机制，从而适应各种平台。</span></strong></div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;">&nbsp;</div><p style="color: #333333; font-size: 14px; padding-top: 0px; padding-bottom: 15px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><a href="http://img1.51cto.com/attachment/201106/233935262.jpg" target="_blank" style="color: #336699; text-decoration: initial; padding: 0px; margin: 0px;"><span style="color: #000000;"><img alt="" src="http://img1.51cto.com/attachment/201106/233935262.jpg" border="0" style="border: none; max-width: 100%; padding: 0px; margin: 0px; vertical-align: top;" /></span></a></p><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"></div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;">从上图中看出，PHP承担HTTP层的职责，而Java承担业务层的职责，他们通过System V Message Queue（消息队列，进程间通讯IPC中的一种）相互沟通，Java需要JNI的支持。</div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;">使用消息队列有以下好处：</div><p style="color: #333333; font-size: 14px; padding-top: 0px; padding-bottom: 15px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"></p><table cellspacing="0" cellpadding="0" width="612" border="1" style="color: #333333; line-height: 26px; padding: 0px; margin: 0px auto; font-size: 12px; font-family: 宋体, 'Arial Narrow', arial, serif;"><tbody style="padding: 0px; margin: 0px;"><tr style="padding: 0px; margin: 0px;"><td valign="top" width="612" style="padding: 0px; margin: 0px;"><div align="left" style="padding: 0px; margin: 0px;"><span style="padding: 0px; margin: 0px;">1.<span style="padding: 0px; margin: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span>使php和java保持独立性</div><div align="left" style="padding: 0px; margin: 0px;"><span style="padding: 0px; margin: 0px;">2.<span style="padding: 0px; margin: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span>有极高的传输速度，大于socket</div><div align="left" style="padding: 0px; margin: 0px;"><span style="padding: 0px; margin: 0px;">3.<span style="padding: 0px; margin: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span>相对于socket方式，Java服务端只向本机提供服务(没有对外侦听端口)，相对安全，易于管理。</div></td></tr></tbody></table><p style="color: #333333; font-size: 14px; padding-top: 0px; padding-bottom: 15px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"></p><div style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px;"><span style="font-size: 24px; padding: 0px; margin: 0px;"><a name="_Toc296514499" style="color: #336699; padding: 0px; margin: 0px;"><span style="padding: 0px; margin: 0px;"><span style="font-size: 14px; padding: 0px; margin: 0px;">1.3</span><span style="padding: 0px; margin: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span><span style="font-size: 14px; padding: 0px; margin: 0px;">通讯内容问题</span></a></span></span></div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;">通信问题解决了，通信内容如何解决呢？</div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="color: #ff0000;"><strong>PHP和Java各自语言内部定义的数据类型，当两种语言互相传输数据时，数据类型怎样进行转换呢？&nbsp;</strong></span></div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;">&nbsp; &nbsp; &nbsp;<strong><span style="color: #ff0000;">（1）</span></strong>Xml: xml确是一种夸平台、能够很好描述对象模型的数据封装技术，但xml体积大传输速率慢，通讯两端解析也比较麻烦。</div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;">&nbsp; &nbsp; &nbsp;<span style="color: #ff0000;">&nbsp;<strong>(2)</strong></span>&nbsp;序列化: 在传输过程中使用序列化和反序列化对象来传输数据是一种公认且比较合理的方式，且两种语言都支持。</div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;">&nbsp;</div><div style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px;"><span style="font-size: 32px; padding: 0px; margin: 0px;"><span style="font-weight: bold;"><a name="_Toc296514501" style="color: #336699; padding: 0px; margin: 0px;"><span style="padding: 0px; margin: 0px;"><span style="font-size: 24px; padding: 0px; margin: 0px;">2</span><span style="padding: 0px; margin: 0px;">&nbsp;&nbsp;&nbsp;</span></span><span style="font-size: 24px; padding: 0px; margin: 0px;">Java</span></a><span style="font-size: 24px; padding: 0px; margin: 0px;"><span style="padding: 0px; margin: 0px;">与php&nbsp;</span><span style="padding: 0px; margin: 0px;">结合选型</span></span></span></span></span></div><div style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><strong><span style="color: #ff0000;">目前已知的PHP与Java在Web间整合技术可分成SOAP（Simple Object Access Protocol）、Quercus、PHP/Java Bridge三种，这些技术可以让PHP与Java在开发Web应用程序时互相使用彼此的程序库。</span></strong></div><p style="color: #333333; font-size: 14px; padding-top: 0px; padding-bottom: 15px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"></p><table cellspacing="0" cellpadding="0" width="621" border="1" style="color: #333333; line-height: 26px; padding: 0px; margin: 0px auto; font-size: 12px; font-family: 宋体, 'Arial Narrow', arial, serif;"><tbody style="padding: 0px; margin: 0px;"><tr style="padding: 0px; margin: 0px;"><td valign="top" width="111" style="padding: 0px; margin: 0px;"><div style="padding: 0px; margin: 0px;">SOAP</div></td><td valign="top" width="510" style="padding: 0px; margin: 0px;"><div align="left" style="padding: 0px; margin: 0px;">SOAP是IBM、Microsoft等公司开发、W3C推荐，用来实现分布式对象技术的协议。SOAP提供了一套以XML来包装程序调用、参数传递与信息回传的机制，借助XML纯文字的特性，可通过HTTP、HTTPS、SMTP等通信管道穿越企业的防火墙。比起CORBA、Java RMI及DCOM这些以专属binary格式传送数据的分布式对象技术协议，SOAP具有与程序语言、平台和硬件无关的特性。</div></td></tr><tr style="padding: 0px; margin: 0px;"><td valign="top" width="111" style="padding: 0px; margin: 0px;"><div style="padding: 0px; margin: 0px;">Quercus</div></td><td valign="top" width="510" style="padding: 0px; margin: 0px;"><div style="padding: 0px; margin: 0px;">Quercus是一个开源 PHP 5 引擎，它已经拥有了纯 Java 的完整实现。Quercus 在 Resin 应用服务器之上运行，利用了负载平衡、代理缓存等 Resin 特性。</div></td></tr><tr style="padding: 0px; margin: 0px;"><td valign="top" width="111" style="padding: 0px; margin: 0px;"><div style="padding: 0px; margin: 0px;">PHP/Java Bridge</div></td><td valign="top" width="510" style="padding: 0px; margin: 0px;"><div style="padding: 0px; margin: 0px;">开源产品有：Php-java-bridge&nbsp;与 LAJP</div></td></tr></tbody></table><p style="color: #333333; font-size: 14px; padding-top: 0px; padding-bottom: 15px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"></p><div style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px;"><span style="font-size: 24px; padding: 0px; margin: 0px;"><a name="_Toc296514502" style="color: #336699; padding: 0px; margin: 0px;"><span style="padding: 0px; margin: 0px;"><span style="font-size: 14px; padding: 0px; margin: 0px;">2.1</span><span style="padding: 0px; margin: 0px;">&nbsp;&nbsp;</span></span><span style="font-size: 14px; padding: 0px; margin: 0px;">选择条件</span></a></span></span></div><div style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px;">&#252;&nbsp;</span>免费、开源</div><div style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px;">&#252;&nbsp;</span>简单易用</div><div style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px;">&#252;&nbsp;</span>高效稳定</div><div style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px;"><span style="font-size: 24px; padding: 0px; margin: 0px;"><a name="_Toc296514503" style="color: #336699; padding: 0px; margin: 0px;"><span style="padding: 0px; margin: 0px;"><span style="font-size: 14px; padding: 0px; margin: 0px;">2.2</span><span style="padding: 0px; margin: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;</span></span><span style="font-size: 14px; padding: 0px; margin: 0px;">LAJP</span></a></span></span></div><div style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px;"><span style="font-size: 18px; padding: 0px; margin: 0px;"><a name="_Toc296514504" style="color: #336699; padding: 0px; margin: 0px;"><span style="padding: 0px; margin: 0px;"><span style="font-size: 14px; padding: 0px; margin: 0px;">2.2.1</span><span style="padding: 0px; margin: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;</span></span><span style="font-size: 14px; padding: 0px; margin: 0px;">特点</span></a></span></span></div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px;">&#216;&nbsp;</span><span style="padding: 0px; margin: 0px;">优势互补:&nbsp;</span>PHP是非常流行的WEB编程脚本语言，有易学、易用、开发部署效率高的特点，<span style="padding: 0px; margin: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>非常适合网页编程；JAVA适合编写具有复杂的业务功能和数据的程序，二者结合可发挥各自优势。</div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px;">&#216;&nbsp;</span><span style="padding: 0px; margin: 0px;">高效稳定</span>：Apache+PHP组合可带来优异的WEB服务稳定性，而JAVA可补充如连接池、事物管理、分布式、对象模型等高端特性。</div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px;">&#216;&nbsp;</span><span style="padding: 0px; margin: 0px;">创新的通信机制</span>: PHP和Java间的通讯方式采用系统消息队列和Socket两种机制，兼顾通讯效率和平台兼容性。</div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px;">&#216;&nbsp;</span><span style="padding: 0px; margin: 0px;">数据类型自动转换机制</span>： PHP数据和Java数据可准确地自动匹配和转换，无须程序员编写解析代码。</div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px;">&#216;&nbsp;</span><span style="padding: 0px; margin: 0px;">易用</span>：LAJP安装配置简单，PHP端和JAVA端编程符合各自的编程习惯。</div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px;">&#216;&nbsp;</span><span style="padding: 0px; margin: 0px;">轻量级</span>：LAJP架构非常轻量级，除了最基本的PHP和Java环境，不需要任何扩充的、第三方的组件、容器。</div><div style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px;">2.2.2<span style="padding: 0px; margin: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>数据类型转换</span></div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;">PHP和Java各有其语言内部定义的数据类型，当PHP数据传送到Java，或Java数据传送到PHP时，LAJP在内部自动地、准确地对他们进行转换，程序员无需进行任何的解码工作。</div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;">&nbsp;</div><p style="color: #333333; font-size: 14px; padding-top: 0px; padding-bottom: 15px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><a href="http://img1.51cto.com/attachment/201106/234017661.jpg" target="_blank" style="color: #336699; text-decoration: initial; padding: 0px; margin: 0px;"><span style="color: #000000;"><img alt="" src="http://img1.51cto.com/attachment/201106/234017661.jpg" border="0" style="border: none; max-width: 100%; padding: 0px; margin: 0px; vertical-align: top;" /></span></a></p><div style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px;"><a name="_Toc296514506" style="color: #336699; padding: 0px; margin: 0px;"><span style="padding: 0px; margin: 0px;"><span style="padding: 0px; margin: 0px;">2.2.3</span><span style="padding: 0px; margin: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;</span></span><span style="padding: 0px; margin: 0px;">LALP&nbsp;</span></a>运行环境</span></div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px;"><span style="color: #cc0000;"><strong>消息队列模式</strong></span></span></div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="color: #cc0000;">环境需要满足System V消息队列的运行：</span></div><ul type="disc" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><li style="padding: 0px; margin: 0px 0px 0px 20px; list-style-type: none; list-style-position: initial;"><span style="color: #cc0000;"><span style="padding: 0px; margin: 0px;">系统</span>&nbsp;目前常见的Unix/Linux系统都可满足php(Apache)、java的运行，其中大部分默认支持System V消息队列。</span></li></ul><ul type="disc" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><li style="padding: 0px; margin: 0px 0px 0px 20px; list-style-type: none; list-style-position: initial;"><span style="color: #cc0000;"><span style="padding: 0px; margin: 0px;">php</span>&nbsp;php需要通过消息队列和java进程通信，按php的说明，php在4.3.0版本以后支持System V消息队列。</span></li></ul><ul type="disc" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><li style="padding: 0px; margin: 0px 0px 0px 20px; list-style-type: none; list-style-position: initial;"><span style="color: #cc0000;"><span style="padding: 0px; margin: 0px;">apache</span>&nbsp;无特殊要求，满足php要求即可。</span></li></ul><ul type="disc" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><li style="padding: 0px; margin: 0px 0px 0px 20px; list-style-type: none; list-style-position: initial;"><span style="color: #cc0000;"><span style="padding: 0px; margin: 0px;">java</span>&nbsp;java版本在1.5以后。</span></li></ul><ul type="disc" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><li style="padding: 0px; margin: 0px 0px 0px 20px; list-style-type: none; list-style-position: initial;"><span style="color: #cc0000;">在Unix/Linux环境中，推荐使用消息队列模式。</span></li></ul><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px;"><span style="color: #cc0000;"><strong>socket模式</strong></span></span></div><ul type="disc" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><li style="padding: 0px; margin: 0px 0px 0px 20px; list-style-type: none; list-style-position: initial;"><span style="color: #cc0000;"><span style="padding: 0px; margin: 0px;">系统</span>&nbsp;没有限制，很难找到不支持TCP/IP的系统。</span></li></ul><ul type="disc" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><li style="padding: 0px; margin: 0px 0px 0px 20px; list-style-type: none; list-style-position: initial;"><span style="color: #cc0000;"><span style="padding: 0px; margin: 0px;">php</span>&nbsp;按php的说明，php版本&gt;=4.1.0支持socket</span></li></ul><ul type="disc" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><li style="padding: 0px; margin: 0px 0px 0px 20px; list-style-type: none; list-style-position: initial;"><span style="color: #cc0000;"><span style="padding: 0px; margin: 0px;">apache</span>&nbsp;无特殊要求，满足php要求即可。</span></li></ul><ul type="disc" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><li style="padding: 0px; margin: 0px 0px 0px 20px; list-style-type: none; list-style-position: initial;"><span style="color: #cc0000;"><span style="padding: 0px; margin: 0px;">java</span>&nbsp;java版本在1.5以后。</span></li></ul><ul type="disc" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><li style="padding: 0px; margin: 0px 0px 0px 20px; list-style-type: none; list-style-position: initial;"><span style="color: #cc0000;">Windows系统只能使用socket模式</span></li></ul><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px;"><span style="color: #cc0000;">在开发过程中可以同时使用这两种模式，比如一般开发者使用Windows环境，而程序部署在Linux系统中，LAJP在模式的配置上和编码无关。</span></span></div><div style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px;"><span style="font-size: 18px; padding: 0px; margin: 0px;"><a name="_Toc296514507" style="color: #336699; padding: 0px; margin: 0px;"><span style="padding: 0px; margin: 0px;"><span style="font-size: 14px; padding: 0px; margin: 0px;">2.2.4</span><span style="padding: 0px; margin: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span><span style="font-size: 14px; padding: 0px; margin: 0px;">部署</span></a></span></span></div><div style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px;">2.2.4.1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;分布式架构</span></div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;">在重要的、关键性的业务场景中，用户交互层和业务层是分开部署的，LAJP在此类架构中可以这样使用：</div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><a href="http://img1.51cto.com/attachment/201106/234045687.jpg" target="_blank" style="color: #336699; text-decoration: initial; padding: 0px; margin: 0px;"><img alt="" src="http://img1.51cto.com/attachment/201106/234045687.jpg" border="0" style="border: none; max-width: 100%; padding: 0px; margin: 0px; vertical-align: top;" /></a>&nbsp;</div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;">WEB服务器中的Java是非常&#8220;薄&#8221;的一层，仅用来连接后面的EJB服务。</div><div style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px;">2.2.4.2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;集群</span></div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;">随着用户访问量的增加，WEB服务往往成为系统中的瓶颈，下面是LAJP在集群中的架构参考：</div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;">&nbsp;</div><p style="color: #333333; font-size: 14px; padding-top: 0px; padding-bottom: 15px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><a href="http://img1.51cto.com/attachment/201106/234148580.jpg" target="_blank" style="color: #336699; text-decoration: initial; padding: 0px; margin: 0px;"><span style="color: #000000;"><img alt="" src="http://img1.51cto.com/attachment/201106/234148580.jpg" border="0" style="border: none; max-width: 100%; padding: 0px; margin: 0px; vertical-align: top;" /></span></a></p><div style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px;">2.2.4.3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;web集群</span></div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;">通过使用socket通讯模式的LAJP，可以搭建出简单的分布式的WEB集群架构：</div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;">&nbsp;</div><p style="color: #333333; font-size: 14px; padding-top: 0px; padding-bottom: 15px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><a href="http://img1.51cto.com/attachment/201106/234215946.jpg" target="_blank" style="color: #336699; text-decoration: initial; padding: 0px; margin: 0px;"><span style="color: #000000;"><img alt="" src="http://img1.51cto.com/attachment/201106/234215946.jpg" width="650" border="0" style="border: none; max-width: 100%; padding: 0px; margin: 0px; vertical-align: top;" /></span></a></p><div style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><span style="padding: 0px; margin: 0px;">2.2.4.4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;复杂架构应用</span></div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;">LAJP使用的灵活性，架构的设计和选择更多在于我们自己的思想，下面的架构参考在WEB层、EJB层都使用了集群：</div><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;">&nbsp;</div><p style="color: #333333; font-size: 14px; padding-top: 0px; padding-bottom: 15px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;"><a href="http://img1.51cto.com/attachment/201106/234232162.jpg" target="_blank" style="color: #336699; text-decoration: initial; padding: 0px; margin: 0px;"><span style="color: #000000;"><img alt="" src="http://img1.51cto.com/attachment/201106/234232162.jpg" width="650" border="0" style="border: none; max-width: 100%; padding: 0px; margin: 0px; vertical-align: top;" /></span></a></p><div align="left" style="color: #333333; font-size: 14px; padding: 0px; margin: 0px; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px;">memcache是分布式的内存对象缓存技术，在PHP中可以非常方便的将Session数据存储在其中，来同步WEB集群中各节点中的数据，从这里也可以体现到PHP在WEB领域相对于Java的&#8220;专业&#8221;。</div><img src ="http://www.cnitblog.com/stomic/aggbug/90236.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/stomic/" target="_blank">大话人生</a> 2015-10-22 18:18 <a href="http://www.cnitblog.com/stomic/archive/2015/10/22/90236.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>（转）Java基础学习总结——Java对象的序列化和反序列化</title><link>http://www.cnitblog.com/stomic/archive/2015/10/22/90235.html</link><dc:creator>大话人生</dc:creator><author>大话人生</author><pubDate>Thu, 22 Oct 2015 09:49:00 GMT</pubDate><guid>http://www.cnitblog.com/stomic/archive/2015/10/22/90235.html</guid><wfw:comment>http://www.cnitblog.com/stomic/comments/90235.html</wfw:comment><comments>http://www.cnitblog.com/stomic/archive/2015/10/22/90235.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/stomic/comments/commentRss/90235.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/stomic/services/trackbacks/90235.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Java基础学习总结&#8212;&#8212;Java对象的序列化和反序列化    一、序列化和反序列化的概念　　把对象转换为字节序列的过程称为对象的序列化。　　把字节序列恢复为对象的过程称为对象的反序列化。　　对象的序列化主要有两种用途：　　1） 把对象的字节序列永久地保存到硬盘上，通常存放在一个文件中；　　2） 在网络上传送对象的字节序列。　　在很多应用中，需要对某些对象进行序列...&nbsp;&nbsp;<a href='http://www.cnitblog.com/stomic/archive/2015/10/22/90235.html'>阅读全文</a><img src ="http://www.cnitblog.com/stomic/aggbug/90235.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/stomic/" target="_blank">大话人生</a> 2015-10-22 17:49 <a href="http://www.cnitblog.com/stomic/archive/2015/10/22/90235.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>（转）Dubbo框架探讨</title><link>http://www.cnitblog.com/stomic/archive/2015/08/25/90185.html</link><dc:creator>大话人生</dc:creator><author>大话人生</author><pubDate>Tue, 25 Aug 2015 09:33:00 GMT</pubDate><guid>http://www.cnitblog.com/stomic/archive/2015/08/25/90185.html</guid><wfw:comment>http://www.cnitblog.com/stomic/comments/90185.html</wfw:comment><comments>http://www.cnitblog.com/stomic/archive/2015/08/25/90185.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/stomic/comments/commentRss/90185.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/stomic/services/trackbacks/90185.html</trackback:ping><description><![CDATA[<h2><span style="line-height: 1.5;">1. Dubbo是什么？</span></h2><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"><span style="line-height: 1.5;">Dubbo是一个分布式服务框架，致力于提供高性能和透明化的RPC远程服务调用方案，以及SOA服务治理方案。简单的说，</span><span style="line-height: 1.5;"><span style="line-height: 1.5;">dubbo就是个服务框架，如果没有分布式的需求，其实是不需要用的，只有在分布式的时候，才有dubbo这样的分布式服务框架的需求，并且本质上是个服务调用的东东，<span style="line-height: 1.5; color: #ff0000;"><strong>说白了就是个远程服务调用的分布式框架（告别<span style="line-height: 1.5;">Web Service模式中的WSdl，以服务者与消费者的方式在dubbo上注册</span>）</strong></span></span></span><br /><span style="line-height: 1.5;">其核心部分包含:</span><br /><span style="line-height: 1.5;">1. 远程通讯: 提供对多种基于长连接的NIO框架抽象封装，包括多种线程模型，序列化，以及&#8220;请求-响应&#8221;模式的信息交换方式。</span><br /><span style="line-height: 1.5;">2. 集群容错: 提供基于接口方法的透明远程过程调用，包括多协议支持，以及软负载均衡，失败容错，地址路由，动态配置等集群支持。</span><br /><span style="line-height: 1.5;">3. 自动发现: 基于注册中心目录服务，使服务消费方能动态的查找服务提供方，使地址透明，使服务提供方可以平滑增加或减少机器。</span></p><h2><a name="t1"></a><span style="line-height: 1.5;">2. Dubbo能做什么？</span></h2><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"><span style="line-height: 1.5;">1.透明化的远程方法调用，就像调用本地方法一样调用远程方法，只需简单配置，没有任何API侵入。 &nbsp; &nbsp; &nbsp;<br />2.软负载均衡及容错机制，可在内网替代F5等硬件负载均衡器，降低成本，减少单点。<br />3. 服务自动注册与发现，不再需要写死服务提供方地址，注册中心基于接口名查询服务提供者的IP地址，并且能够平滑添加或删除服务提供者。<br /><br /></span><span style="line-height: 1.5;">Dubbo采用全Spring配置方式，透明化接入应用，对应用没有任何API侵入，只需用Spring加载Dubbo的配置即可，Dubbo基于Spring的Schema扩展进行加载。</span><span style="line-height: 1.5;"><br /></span></p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"><span style="line-height: 1.5; color: #ff0000;"><strong>之前使用Web Service，我想测试接口可以通过模拟消息的方式通过soapui或LR进行功能测试或性能测试。但现在使用Dubbo，接口之间不能直接交互，我尝试通过模拟消费者地址测试，结果不堪入目，再而使用jmeter通过junit进行测试，但还是需要往dubbo上去注册，如果再不给提供源代码的前提下，这个测试用例不好写啊....</strong></span></p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">&nbsp;</p><h2><a name="t2"></a>3. dubbo的架构</h2><div style="font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19.5px;"><span style="line-height: 1.5;">dubbo</span><span style="line-height: 1.5;">架构图如下所示：</span></div><div style="font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19.5px;">&nbsp;</div><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"><img src="http://img.blog.csdn.net/20131224140734734" alt="" style="border: 0px;" /></p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">&nbsp;</p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">&nbsp;</p><h4><a name="t3"></a>节点角色说明：</h4><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Provider:&nbsp;暴露服务的服务提供方。</p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Consumer:&nbsp;调用远程服务的服务消费方。</p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Registry:&nbsp;服务注册与发现的注册中心。</p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Monitor:&nbsp;统计服务的调用次调和调用时间的监控中心。</p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Container:&nbsp;服务运行容器。</p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"><span style="line-height: 1.5; color: #ff0000;"><strong>这点我觉得非常好，角色分明，可以根据每个节点角色的状态来确定该服务是否正常。</strong></span></p><h4><a name="t4"></a></h4><h4><a name="t5"></a>调用关系说明：</h4><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"><span style="line-height: 1.5;">0 服务容器负责启动，加载，运行服务提供者。</span></p><h4><a name="t6"></a><span style="line-height: 1.5;">1. 服务提供者在启动时，向注册中心注册自己提供的服务。</span></h4><h4><a name="t7"></a><span style="line-height: 1.5;">2. 服务消费者在启动时，向注册中心订阅自己所需的服务。</span></h4><h4><a name="t8"></a><span style="line-height: 1.5;">3. 注册中心返回服务提供者地址列表给消费者，如果有变更，注册中心将基于长连接推送变更数据给消费者。</span></h4><h4><a name="t9"></a><span style="line-height: 1.5;">4. 服务消费者，从提供者地址列表中，基于软负载均衡算法，选一台提供者进行调用，如果调用失败，再选另一台调用。</span></h4><h4><a name="t10"></a><span style="line-height: 1.5;">5. 服务消费者和提供者，在内存中累计调用次数和调用时间，定时每分钟发送一次统计数据到监控中心。</span></h4><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"><span style="line-height: 1.5; color: #ff0000;"><strong>dubbo的容错性显而易见，性能方面还没有还得及测，我们系统某页面需要掉5次接口，本来想建议做个缓存，但业务关系不能采纳，还需要研究下dubbo的性能调优问题...</strong></span></p><h2><a name="t11"></a>4. dubbo使用方法。</h2><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"><span style="line-height: 1.5;">Dubbo采用全Spring配置方式，透明化接入应用，对应用没有任何API侵入，只需用Spring加载Dubbo的配置即可，Dubbo基于Spring的Schema扩展进行加载。</span><span style="line-height: 1.5;">如果不想使用Spring配置，而希望通过API的方式进行调用（不推荐）</span></p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"><span style="line-height: 1.5;">下面我们就来看看spring配置方式的写法:</span></p><h4><a name="t12"></a>服务提供者：</h4><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"><span style="line-height: 1.5;">1.&nbsp;下载zookeeper注册中心，下载地址：<a href="http://www.apache.org/dyn/closer.cgi/zookeeper/" target="_blank" style="color: navy;"><span style="line-height: 1.5;">http://www.apache.org/dyn/closer.cgi/zookeeper/</span></a>&nbsp;&nbsp;下载后解压即可，进入D:\apach-zookeeper-3.4.5\bin，</span></p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"><span style="line-height: 1.5;">双击zkServer.cmd启动注册中心服务。</span></p><h4><a name="t13"></a><span style="line-height: 1.5;">2.&nbsp;定义服务接口: (该接口需单独打包，在服务提供方和消费方共享)</span></h4><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">&nbsp;</p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">&nbsp;<strong><span style="line-height: 1.5; color: #ff0000;">下面这个例子不错，写的很详细可以做个model.</span></strong></p><div bg_html"="" style="word-break: break-word;"><ol start="1" style="padding-left: 50px;"><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;"><span style="line-height: 1.5;">package&nbsp;com.unj.dubbotest.provider;&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">import&nbsp;java.util.List;&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">public&nbsp;interface&nbsp;DemoService&nbsp;{&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;sayHello(String&nbsp;name);&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;List&nbsp;getUsers();&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">}&nbsp;&nbsp;</span></li></ol></div><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"><br /><span style="line-height: 1.5;">在服务提供方实现接口：(对服务消费方隐藏实现)</span></p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">&nbsp;</p><div bg_html"="" style="word-break: break-word;"><ol start="1" style="padding-left: 50px;"><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;"><span style="line-height: 1.5;">package&nbsp;com.unj.dubbotest.provider;&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">import&nbsp;java.util.ArrayList;&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">import&nbsp;java.util.LinkedList;&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">import&nbsp;java.util.List;&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">public&nbsp;class&nbsp;DemoServiceImpl&nbsp;implements&nbsp;DemoService{&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;String&nbsp;sayHello(String&nbsp;name)&nbsp;{&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;"Hello&nbsp;"&nbsp;+&nbsp;name;&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;List&nbsp;getUsers()&nbsp;{&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List&nbsp;<span style="line-height: 1.5;">list</span><span style="line-height: 1.5;">&nbsp;=&nbsp;</span><span style="line-height: 1.5;">new</span><span style="line-height: 1.5;">&nbsp;ArrayList();&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;User&nbsp;<span style="line-height: 1.5;">u1</span><span style="line-height: 1.5;">&nbsp;=&nbsp;</span><span style="line-height: 1.5;">new</span><span style="line-height: 1.5;">&nbsp;User();&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;u1.setName("jack");&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;u1.setAge(20);&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;u1.setSex("男");&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;User&nbsp;<span style="line-height: 1.5;">u2</span><span style="line-height: 1.5;">&nbsp;=&nbsp;</span><span style="line-height: 1.5;">new</span><span style="line-height: 1.5;">&nbsp;User();&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;u2.setName("tom");&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;u2.setAge(21);&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;u2.setSex("女");&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;User&nbsp;<span style="line-height: 1.5;">u3</span><span style="line-height: 1.5;">&nbsp;=&nbsp;</span><span style="line-height: 1.5;">new</span><span style="line-height: 1.5;">&nbsp;User();&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;u3.setName("rose");&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;u3.setAge(19);&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;u3.setSex("女");&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.add(u1);&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.add(u2);&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.add(u3);&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;list;&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">}&nbsp;&nbsp;</span></li></ol></div><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">&nbsp;</p><div style="font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19.5px;">用Spring配置声明暴露服务：</div><div bg_html"="" style="word-break: break-word;"><ol start="1" style="padding-left: 50px;"><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;"><span style="line-height: 1.5;">&lt;?</span><span style="line-height: 1.5;">xml</span>&nbsp;<span style="line-height: 1.5;">version</span><span style="line-height: 1.5;">=</span><span style="line-height: 1.5;">"1.0"</span>&nbsp;<span style="line-height: 1.5;">encoding</span><span style="line-height: 1.5;">=</span><span style="line-height: 1.5;">"UTF-8"</span><span style="line-height: 1.5;">?&gt;</span><span style="line-height: 1.5;">&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;"><span style="line-height: 1.5;">&lt;</span><span style="line-height: 1.5;">beans</span>&nbsp;<span style="line-height: 1.5;">xmlns</span><span style="line-height: 1.5;">=</span><span style="line-height: 1.5;">"http://www.springframework.org/schema/beans"</span><span style="line-height: 1.5;">&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5;">xmlns:xsi</span><span style="line-height: 1.5;">=</span><span style="line-height: 1.5;">"http://www.w3.org/2001/XMLSchema-instance"</span><span style="line-height: 1.5;">&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5;">xmlns:dubbo</span><span style="line-height: 1.5;">=</span><span style="line-height: 1.5;">"http://code.alibabatech.com/schema/dubbo"</span><span style="line-height: 1.5;">&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5;">xsi:schemaLocation</span><span style="line-height: 1.5;">="http://www.springframework.org/schema/beans&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;http://www.springframework.org/schema/beans/spring-beans.xsd&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;http://code.alibabatech.com/schema/dubbo&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;http://code.alibabatech.com/schema/dubbo/dubbo.xsd&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"<span style="line-height: 1.5;">&gt;</span><span style="line-height: 1.5;">&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5;">&lt;!--&nbsp;具体的实现bean&nbsp;--&gt;</span><span style="line-height: 1.5;">&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5;">&lt;</span><span style="line-height: 1.5;">bean</span>&nbsp;<span style="line-height: 1.5;">id</span><span style="line-height: 1.5;">=</span><span style="line-height: 1.5;">"demoService"</span>&nbsp;<span style="line-height: 1.5;">class</span><span style="line-height: 1.5;">=</span><span style="line-height: 1.5;">"com.unj.dubbotest.provider.DemoServiceImpl"</span>&nbsp;<span style="line-height: 1.5;">/&gt;</span><span style="line-height: 1.5;">&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5;">&lt;!--&nbsp;提供方应用信息，用于计算依赖关系&nbsp;--&gt;</span><span style="line-height: 1.5;">&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5;">&lt;</span><span style="line-height: 1.5;">dubbo:application</span>&nbsp;<span style="line-height: 1.5;">name</span><span style="line-height: 1.5;">=</span><span style="line-height: 1.5;">"xixi_provider"</span><span style="line-height: 1.5;">&nbsp;&nbsp;</span><span style="line-height: 1.5;">/&gt;</span><span style="line-height: 1.5;">&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;使用multicast广播注册中心暴露服务地址&nbsp;&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5;">&lt;</span><span style="line-height: 1.5;">dubbo:registry</span>&nbsp;<span style="line-height: 1.5;">address</span><span style="line-height: 1.5;">=</span><span style="line-height: 1.5;">"multicast://224.5.6.7:1234"</span>&nbsp;<span style="line-height: 1.5;">/&gt;</span><span style="line-height: 1.5;">--</span><span style="line-height: 1.5;">&gt;</span><span style="line-height: 1.5;">&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5;">&lt;!--&nbsp;使用zookeeper注册中心暴露服务地址&nbsp;--&gt;</span><span style="line-height: 1.5;">&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5;">&lt;</span><span style="line-height: 1.5;">dubbo:registry</span>&nbsp;<span style="line-height: 1.5;">address</span><span style="line-height: 1.5;">=</span><span style="line-height: 1.5;">"zookeeper://127.0.0.1:2181"</span>&nbsp;<span style="line-height: 1.5;">/&gt;</span><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5;">&lt;!--&nbsp;用dubbo协议在20880端口暴露服务&nbsp;--&gt;</span><span style="line-height: 1.5;">&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5;">&lt;</span><span style="line-height: 1.5;">dubbo:protocol</span>&nbsp;<span style="line-height: 1.5;">name</span><span style="line-height: 1.5;">=</span><span style="line-height: 1.5;">"dubbo"</span>&nbsp;<span style="line-height: 1.5;">port</span><span style="line-height: 1.5;">=</span><span style="line-height: 1.5;">"20880"</span>&nbsp;<span style="line-height: 1.5;">/&gt;</span><span style="line-height: 1.5;">&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5;">&lt;!--&nbsp;声明需要暴露的服务接口&nbsp;--&gt;</span><span style="line-height: 1.5;">&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5;">&lt;</span><span style="line-height: 1.5;">dubbo:service</span>&nbsp;<span style="line-height: 1.5;">interface</span><span style="line-height: 1.5;">=</span><span style="line-height: 1.5;">"com.unj.dubbotest.provider.DemoService"</span>&nbsp;<span style="line-height: 1.5;">ref</span><span style="line-height: 1.5;">=</span><span style="line-height: 1.5;">"demoService"</span>&nbsp;<span style="line-height: 1.5;">/&gt;</span><span style="line-height: 1.5;">&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;"><span style="line-height: 1.5;">&lt;/</span><span style="line-height: 1.5;">beans</span><span style="line-height: 1.5;">&gt;</span><span style="line-height: 1.5;">&nbsp;&nbsp;</span></span></li></ol></div><div style="font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19.5px;">加载Spring配置，启动服务：</div><div style="font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19.5px;"><div bg_html"="" style="word-break: break-word;"><ol start="1" style="padding-left: 50px;"><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;"><span style="line-height: 1.5;">package&nbsp;com.unj.dubbotest.provider;&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">import&nbsp;org.springframework.context.support.ClassPathXmlApplicationContext;&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">public&nbsp;class&nbsp;Provider&nbsp;{&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args)&nbsp;throws&nbsp;Exception&nbsp;{&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ClassPathXmlApplicationContext&nbsp;<span style="line-height: 1.5;">context</span><span style="line-height: 1.5;">&nbsp;=&nbsp;</span><span style="line-height: 1.5;">new</span><span style="line-height: 1.5;">&nbsp;ClassPathXmlApplicationContext(new&nbsp;String[]&nbsp;{"applicationContext.xml"});&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context.start();&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.in.read();&nbsp;//&nbsp;为保证服务一直开着，利用输入流的阻塞来模拟&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">}&nbsp;&nbsp;</span></li></ol></div><br /><h4><a name="t14"></a>服务消费者：</h4><p style="line-height: 1.5; margin: 10px auto;"><strong><span style="line-height: 1.5; color: #ff0000;">&nbsp;applicationContext-dubbo.xml 中注册自己需要调用的接口，我刚开始测试的时候需要的接口很多，所以把这个文件写的满满的，后来熟悉了把接口按业务类型分开，写了N多个<strong><span style="line-height: 1.5;">&nbsp;applicationContext-dubbo-***.xml 简练多了 》。&nbsp;</span></strong></span></strong></p><p style="line-height: 1.5; margin: 10px auto;">&nbsp;</p></div><div style="font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19.5px;"><span style="line-height: 1.5;">1.通过Spring配置引用远程服务：</span><div><div bg_html"="" style="word-break: break-word;"><ol start="1" style="padding-left: 50px;"><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;"><span style="line-height: 1.5;">&lt;?</span><span style="line-height: 1.5;">xml</span>&nbsp;<span style="line-height: 1.5;">version</span><span style="line-height: 1.5;">=</span><span style="line-height: 1.5;">"1.0"</span>&nbsp;<span style="line-height: 1.5;">encoding</span><span style="line-height: 1.5;">=</span><span style="line-height: 1.5;">"UTF-8"</span><span style="line-height: 1.5;">?&gt;</span><span style="line-height: 1.5;">&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;"><span style="line-height: 1.5;">&lt;</span><span style="line-height: 1.5;">beans</span>&nbsp;<span style="line-height: 1.5;">xmlns</span><span style="line-height: 1.5;">=</span><span style="line-height: 1.5;">"http://www.springframework.org/schema/beans"</span><span style="line-height: 1.5;">&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5;">xmlns:xsi</span><span style="line-height: 1.5;">=</span><span style="line-height: 1.5;">"http://www.w3.org/2001/XMLSchema-instance"</span>&nbsp;<span style="line-height: 1.5;">xmlns:dubbo</span><span style="line-height: 1.5;">=</span><span style="line-height: 1.5;">"http://code.alibabatech.com/schema/dubbo"</span><span style="line-height: 1.5;">&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5;">xsi:schemaLocation</span><span style="line-height: 1.5;">="http://www.springframework.org/schema/beans&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;http://www.springframework.org/schema/beans/spring-beans.xsd&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;http://code.alibabatech.com/schema/dubbo&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;http://code.alibabatech.com/schema/dubbo/dubbo.xsd&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"<span style="line-height: 1.5;">&gt;</span><span style="line-height: 1.5;">&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5;">&lt;!--&nbsp;消费方应用名，用于计算依赖关系，不是匹配条件，不要与提供方一样&nbsp;--&gt;</span><span style="line-height: 1.5;">&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5;">&lt;</span><span style="line-height: 1.5;">dubbo:application</span>&nbsp;<span style="line-height: 1.5;">name</span><span style="line-height: 1.5;">=</span><span style="line-height: 1.5;">"hehe_consumer"</span>&nbsp;<span style="line-height: 1.5;">/&gt;</span><span style="line-height: 1.5;">&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5;">&lt;!--&nbsp;使用zookeeper注册中心暴露服务地址&nbsp;--&gt;</span><span style="line-height: 1.5;">&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5;">&lt;!--&nbsp;&lt;dubbo:registry&nbsp;address="multicast://224.5.6.7:1234"&nbsp;/&gt;&nbsp;--&gt;</span><span style="line-height: 1.5;">&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5;">&lt;</span><span style="line-height: 1.5;">dubbo:registry</span>&nbsp;<span style="line-height: 1.5;">address</span><span style="line-height: 1.5;">=</span><span style="line-height: 1.5;">"zookeeper://127.0.0.1:2181"</span>&nbsp;<span style="line-height: 1.5;">/&gt;</span><span style="line-height: 1.5;">&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5;">&lt;!--&nbsp;生成远程服务代理，可以像使用本地bean一样使用demoService&nbsp;--&gt;</span><span style="line-height: 1.5;">&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5;">&lt;</span><span style="line-height: 1.5;">dubbo:reference</span>&nbsp;<span style="line-height: 1.5;">id</span><span style="line-height: 1.5;">=</span><span style="line-height: 1.5;">"demoService"</span><span style="line-height: 1.5;">&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 1.5;">interface</span><span style="line-height: 1.5;">=</span><span style="line-height: 1.5;">"com.unj.dubbotest.provider.DemoService"</span>&nbsp;<span style="line-height: 1.5;">/&gt;</span><span style="line-height: 1.5;">&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;"><span style="line-height: 1.5;">&lt;/</span><span style="line-height: 1.5;">beans</span><span style="line-height: 1.5;">&gt;</span><span style="line-height: 1.5;">&nbsp;&nbsp;</span></span></li></ol></div><br /><div><span style="line-height: 1.5;">2.加载Spring配置，并调用远程服务：</span></div><div><div bg_html"="" style="word-break: break-word;"><ol start="1" style="padding-left: 50px;"><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;"><span style="line-height: 1.5;">package&nbsp;com.alibaba.dubbo.demo.pp;&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">import&nbsp;java.util.List;&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">import&nbsp;org.springframework.context.support.ClassPathXmlApplicationContext;&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">import&nbsp;com.unj.dubbotest.provider.DemoService;&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">public&nbsp;class&nbsp;Consumer&nbsp;{&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args)&nbsp;throws&nbsp;Exception&nbsp;{&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ClassPathXmlApplicationContext&nbsp;<span style="line-height: 1.5;">context</span><span style="line-height: 1.5;">&nbsp;=&nbsp;</span><span style="line-height: 1.5;">new</span><span style="line-height: 1.5;">&nbsp;ClassPathXmlApplicationContext(&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;String[]&nbsp;{&nbsp;"applicationContext.xml"&nbsp;});&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context.start();&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DemoService&nbsp;<span style="line-height: 1.5;">demoService</span><span style="line-height: 1.5;">&nbsp;=&nbsp;(DemoService)&nbsp;context.getBean("demoService");&nbsp;//&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;<span style="line-height: 1.5;">hello</span><span style="line-height: 1.5;">&nbsp;=&nbsp;</span><span style="line-height: 1.5;">demoService</span><span style="line-height: 1.5;">.sayHello("tom");&nbsp;//&nbsp;ִ&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(hello);&nbsp;//&nbsp;&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List&nbsp;<span style="line-height: 1.5;">list</span><span style="line-height: 1.5;">&nbsp;=&nbsp;</span><span style="line-height: 1.5;">demoService</span><span style="line-height: 1.5;">.getUsers();&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(list&nbsp;!=&nbsp;null&nbsp;&amp;&amp;&nbsp;list.size()&nbsp;<span style="line-height: 1.5;">&gt;</span><span style="line-height: 1.5;">&nbsp;0)&nbsp;{&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(int&nbsp;<span style="line-height: 1.5;">i</span><span style="line-height: 1.5;">&nbsp;=&nbsp;</span><span style="line-height: 1.5;">0</span><span style="line-height: 1.5;">;&nbsp;i&nbsp;</span><span style="line-height: 1.5;">&lt;</span>&nbsp;<span style="line-height: 1.5;">list.size</span><span style="line-height: 1.5;">();&nbsp;i++)&nbsp;{&nbsp;&nbsp;</span></span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(list.get(i));&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;System.out.println(demoService.hehe());&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.in.read();&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">&nbsp;&nbsp;</span></li><li style="list-style-type: decimal; line-height: 1.6;"><span style="line-height: 1.5;">}&nbsp;&nbsp;</span></li></ol></div></div></div></div><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"><span style="line-height: 1.5;">调用结果为：</span></p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">&nbsp;</p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"><span style="line-height: 1.5;"><img src="http://img.blog.csdn.net/20131224152934546" alt="" style="border: 0px;" /><br /></span></p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"><span style="line-height: 1.5;">dubbo管理页面：</span></p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"><strong><span style="line-height: 1.5; color: #ff0000;">这个管理页面还需要部署一个环境的，一开始我还以为是dubbo自带的，找了半天没有找到....</span></strong></p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">&nbsp;</p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"><span style="line-height: 1.5;"><img src="http://img.blog.csdn.net/20131224152811531" alt="" style="border: 0px;" /><br /></span></p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">&nbsp;</p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">&nbsp;</p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">&nbsp;</p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">&nbsp;</p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"><span style="line-height: 1.5;">应用页面：</span></p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"><img src="http://img.blog.csdn.net/20131224152822062" alt="" style="border: 0px;" /></p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">&nbsp;</p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">&nbsp;</p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">&nbsp;</p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">&nbsp;</p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">提供者页面:</p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"><img src="http://img.blog.csdn.net/20131224153419968" alt="" style="border: 0px;" /></p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">&nbsp;</p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">&nbsp;</p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">&nbsp;</p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">&nbsp;</p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">消费者页面：</p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"><img src="http://img.blog.csdn.net/20131224152829015" alt="" style="border: 0px;" /></p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">&nbsp;</p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">&nbsp;</p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">&nbsp;</p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">&nbsp;</p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">服务页面：</p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"><img src="http://img.blog.csdn.net/20131224152846578" alt="" style="border: 0px;" /></p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"><span style="line-height: 1.5; color: #ff0000;">测试是否成功，我觉得只要看看状态是否正常，就ok了 ....</span></p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">&nbsp;</p><p style="font-size: 13px; line-height: 19.5px; margin: 10px auto; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;"><span style="line-height: 1.5;"><span style="line-height: 1.5;">案例代码下载：<a href="http://download.csdn.net/detail/yiyu1/7116319" style="color: navy;">http://download.csdn.net/detail/yiyu1/7116319</a></span></span></p><img src ="http://www.cnitblog.com/stomic/aggbug/90185.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/stomic/" target="_blank">大话人生</a> 2015-08-25 17:33 <a href="http://www.cnitblog.com/stomic/archive/2015/08/25/90185.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转：Java学习路线图，专为新手定制的Java学习计划建议</title><link>http://www.cnitblog.com/stomic/archive/2015/07/14/90145.html</link><dc:creator>大话人生</dc:creator><author>大话人生</author><pubDate>Tue, 14 Jul 2015 07:08:00 GMT</pubDate><guid>http://www.cnitblog.com/stomic/archive/2015/07/14/90145.html</guid><wfw:comment>http://www.cnitblog.com/stomic/comments/90145.html</wfw:comment><comments>http://www.cnitblog.com/stomic/archive/2015/07/14/90145.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/stomic/comments/commentRss/90145.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/stomic/services/trackbacks/90145.html</trackback:ping><description><![CDATA[<p style="color: #333333; font-family: Arial; font-size: 14px; line-height: 26px;">从网上发现这篇文章，发现和我写的一篇关于《<a href="http://blog.csdn.net/jinxfei/archive/2009/09/27/4602449.aspx" style="color: #336699;">知识体系</a>》的文章互相呼应，就转过来了。</p><p style="color: #333333; font-family: Arial; font-size: 14px; line-height: 26px;">转自：<a title="http://tieba.baidu.com/f?kz=692446591" href="http://tieba.baidu.com/f?kz=692446591" style="color: #336699;">http://tieba.baidu.com/f?kz=692446591</a></p><p style="color: #333333; font-family: Arial; font-size: 14px; line-height: 26px;">怎么学习Java，这是很多新手经常会问我的问题，现在我简单描述下一个Java初学者到就业要学到的一些东西：&nbsp;<br />&nbsp;&nbsp;&nbsp; 首先要明白Java体系设计到得三个方面：J2SE,J2EE,J2ME（KJAVA）。J2SE，Java 2 Platform Standard Edition，我们经常说到的JDK，就主要指的这个，它是三者的基础，属于桌面级应用开发，这部分如果学得好很容易拓展J2EE和J2ME。J2ME，The Micro Edition of the Java 2 Platform。主要用于嵌入式Java，如手机，PDA等等。J2EE，Java 2 Platform，Enterprise Edition，就是所谓的企业级Java，适合企业的大型应用开发。&nbsp;<br />J2SE：&nbsp;<br />&nbsp;&nbsp;&nbsp; 新手最初学习的时候先要从J2SE开始学起，所包含的内容主要分为：面向对象概念的理解、Java基本语法的学习，Java桌面图形界面应用程序的开发，掌握常用的Java API等（关键是要学会怎样查阅）。&nbsp;<br />重点：Java基本语法（循环结构，数据类型，数组，运算符等）、Swing，awt，事件机制、文件输入输出流处理等<br />难点：面向对象思想的理解（接口、类等）、线程、socket网络编程等&nbsp;<br />视频教程推荐：孙鑫的Java基础视频教程、张孝祥的Java基础视频教程，讲的都很细，而且这两位老师在教学方面都有很好的经验。&nbsp;<br />J2EE：&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在学习了J2SE之后，你可以尝试着慢慢过渡到J2EE，当然，学习J2EE海需要很多非JAVA技术的支撑，比如数据库技术，网页编程技术等等，待会我会详细介绍这两方面的内容。J2EE有三个必学的框架，如果你说你学了J2EE，但又不会这三个框架的话，那会让人笑掉大牙，这三个框架分别是Struts、Spring和Hibernate，虽然这三个框架应用很广，但不代表这三个框架就代表了J2EE，J2EE还有很多其他的东西，比如EJB，作为一款重量级（此重量级不是指重量级选手那个意思，此重量级非彼重量级）框架，虽然这个应用慢慢的再被其他框架所取代，但EJB3.0的出现也给它带回一些生机，作为一个分布式应用的框架，也是大家要去学习和了解的知识。&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 当然，刚才说到J2EE包含的范围很广，即使我把我所了解的所有技术说出来，也并不能代表J2EE，这是一个很深很广的学问，需要大家以后再工作的时候慢慢去发现了。我所了解的还包括：&nbsp;<br />JDBC:Java数据库连接对象，基础中的基础，Hibernate也只是对它的封装而已&nbsp;<br />JNDI: Java 命名与目录接口，J2EE重要规范之一&nbsp;<br />EJBS: 上面已经提到过了&nbsp;<br />RMI: 提供远程调用方法的支持，主要用于程序分布式开发&nbsp;<br />JMS: Java消息服务，中间件技术&nbsp;<br />JAVA IDL: 提供J2EE平台与CORBA交互能力和互联能力的技术&nbsp;<br />JTS: 组件事务监视器&nbsp;<br />JTA: 事务划分的一个技术&nbsp;<br />JAVAMAIL: Java中的邮件技术&nbsp;<br />JAF: Java启动框架,没研究过&nbsp;<br />Log4j，一款日志处理的框架应用&nbsp;<br />Junit：单元测试的好帮手&nbsp;<br />freemarker、velocity：两款不错的模板引擎&nbsp;<br />与Flash的交互Flex：目前很多的SNS应用就是使用到了这个技术&nbsp;<br />Web services:想知道我们论坛天气预报的效果是怎么做的吗？请关注这个技术&nbsp;<br />SOA:面向服务架构，未来技术发展的趋势之一&nbsp;<br />&#8230;&#8230;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 不过前面介绍到得这些都不是J2EE的基础,是属于框架应用级别的.要真正把上面说到的知识掌握好,还是的学习J2EE最核心的东西:JDBC、JSP、servlet和JavaBean,后面三个也是学习SSH的基础(Struts/Spring/Hibernate的简称).鉴于J2EE的内容太过复杂,建议大家最初只学习: JSP, servlet和JavaBean，等这个基础掌握好再把SSH学习了，再对其他J2EE技术有个大致的了解就可以出去找工作了。当然，找工作的前提除了把Java学习好，还会有一些其他的技术也是必须要掌握的。</p><p style="color: #333333; font-family: Arial; font-size: 14px; line-height: 26px;">-_- 我很简单,Java却要求我学这么多复杂的东西。除了这些技术的东西，在这阶段，大家更多的是会接触到比如设计模式的东西，比如工厂模式、桥梁模式、单例模式等等，还要学习建模思想（比如UML建模等等）和软件生命周期等等。这些是升华大家编程思想的手段和途径。&nbsp;<br />数据库技术:&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; 数据库几乎是程序中不可或缺的一部分,在整个软件开发中更是占据了重要作用.数据库在整个软件中扮演的是地基的角色,你要修房子,就要先打好地基,你要做软件,就要先设计好的数据库.目前数据库几乎都是关系型数据库,代表的有:&nbsp;<br />SQL Server,目前最新的好像是2008,我不是很喜欢追赶时髦,用的还是2005,不过也很不错了,在此之前还有2000.&nbsp;<br />MySQL,最知名的开源数据库之一,我很喜欢它的小巧耐用,学过SQL SERVER数据库再学它,无师自通,易如反掌.&nbsp;<br />ORACLE.甲骨文公司的产品,大型数据库,正版的一般公司买不起.只有看看了,不过现在Java开发60%都是会使用到这个数据库,再加上现在甲骨文已经把sun公司收购了,JAVA和ORACLE得关系更加暧昧,各位得多花些时间在这上面了.&nbsp;<br />除了这些，你还应该了解一些桌面应用软件开发用到的数据库，比如说sqlite。你在制作安装程序的时候可以把这个数据库打包进你的安装程序。&nbsp;<br />网页编程基础:&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; 网页编程基础要学的内容也比较多,但主要集中在以下这三个技术之上,大家每天看的各种样式的网页都是它们呈现的:&nbsp;<br />HTML:超文本标记语言&nbsp;<br />CSS:层叠样式表&nbsp;<br />Javascript:浏览器客户端脚本语言&nbsp;<br />现在更是流行各种JavaScript库,比如:Jquery、ExtJs等，你要是会其中的某一个库的使用，找工作so easy。&nbsp;<br />J2ME：&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; 如果你在学习了以上技术还不过瘾，可以再学习手机程序的开发，就我个人看来，开发手机程序技术其实蛮简单的，难点在于优化，比如怎么让你写的程序尽量的节约手机资源，&#8220;代码诚可贵，手机价更高&#8220;，所以不得不比PC机多考虑很多成本和实用性问题。J2ME的学习的话，切忌不要单纯的再模拟器上测试，一定要找真机测试，真机和模拟器的效果之间差别是很大的。更多手机开发技术，有兴趣的朋友可以和我一起探讨。&nbsp;<br />开发工具：&nbsp;<br />&nbsp;&nbsp;&nbsp; 开发工具的选择主要还是看大家的习惯，我个人比较喜欢使用eclispe，功能很强大，也很好拓展其他的功能。当让初学你也可以选择JCreator，或者最好就直接用记事本。等你熟悉了Java代码之后，就可以使用JBuilder、eclispe或者netbeans这一类的工具了。&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; 先说到这里先，以后大家一起完善这个帖子。尽量再给大家整理一些学习的资源在这里。也欢迎大家一起整理我文章中提到的一些技术资源和开发工具。最后，再和大家分享一句话：生命欣欣向荣，唯奋斗不息。也和大家分享一幅Java学习路线图：&nbsp;<br /><a href="http://hi.csdn.net/attachment/201005/4/0_1272935756z51q.gif" style="color: #336699;"><img title="untitled" height="1024" alt="untitled" src="http://hi.csdn.net/attachment/201005/4/0_1272935769KNxA.gif" width="604" border="0" style="border: 0px; max-width: 100%; display: inline;" /></a></p><img src ="http://www.cnitblog.com/stomic/aggbug/90145.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/stomic/" target="_blank">大话人生</a> 2015-07-14 15:08 <a href="http://www.cnitblog.com/stomic/archive/2015/07/14/90145.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>（转）接口的作用</title><link>http://www.cnitblog.com/stomic/archive/2013/08/26/88463.html</link><dc:creator>大话人生</dc:creator><author>大话人生</author><pubDate>Mon, 26 Aug 2013 09:09:00 GMT</pubDate><guid>http://www.cnitblog.com/stomic/archive/2013/08/26/88463.html</guid><wfw:comment>http://www.cnitblog.com/stomic/comments/88463.html</wfw:comment><comments>http://www.cnitblog.com/stomic/archive/2013/08/26/88463.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/stomic/comments/commentRss/88463.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/stomic/services/trackbacks/88463.html</trackback:ping><description><![CDATA[<div><div id="cnblogs_post_body"><span style="font-size: 8pt"><span style="font-size: 10pt"><span style="font-size: small">C# 接口是一个让很多初学C#者容易迷糊的东西，用起来好像很简单，定义接口，里面包含方法，但没有方法具体实现的代码，然后在继承该接口的类里面要实现接口 的所有方法的代码，但没有真正认识到接口的作用的时候就觉得用接口是多此一举，当然你这样想那是绝对绝对错误的，比尔盖茨的微软请的员工都是比盖茨还聪明 的人，他们的C#能添这样的多足吗？！关于接口的作用，网上有一位就真的深入浅出给我们做了很好理解的分析。 </span></span></span> <div><span style="font-size: 8pt"><span style="font-size: 10pt"><span style="font-size: small">我们定义一个接口<br />public interface IBark<br />{<br />&nbsp;&nbsp;&nbsp; void Bark();<br />}<br />再定义一个类,继承于IBark,并且必需实现其中的Bark()方法<br />public class Dog:IBark<br />{<br />&nbsp;&nbsp;&nbsp; public Dog()<br />&nbsp;&nbsp;&nbsp; {}<br />&nbsp;&nbsp;&nbsp; public void Bark()<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Consol.write("汪汪");<br />&nbsp;&nbsp;&nbsp;&nbsp; }<br />}<br />然后,声明Dog的一个实例,并调用Bark()方法<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dog 旺财=new Dog();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 旺财.Bark();<br />试想一样,若是想调用Bark()方法,只需要在Dog()中声明这样的一个方法不就行了吗,干什么还要用接口呢.因为接口中并没有Bark()具体实现.真的实现还是要在Dog()中.那么使用接口不是多此一举吗?<br />还有人是这样说的:从<span style="color: #0000ff"><strong>接口的定义方面来说,接口其实就是类和类之间的一种协定,一种约束.</strong></span>还 拿上面的例子来说.所有继承了IBark接口的类中必需实现Bark()方法.那么从用户(使用类的用户)的角度来说,如果他知道了某个类是继承于 IBark接口,那么他就可以放心大胆的调用Bark()方法,而不用管Bark()方法具体是如何实现的.比如,我们另外写了一个类.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public class Cat:IBark<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Cat()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void Bark()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Consol.write("喵喵");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />当用户用到Cat类或是Dog类的时候,知道他们继承于IBark,那么不用管类里的具体实现,而就可以直接调用Bark()方法,因为这两个类中肯定有关于Bark()方法的具体实现.<br /><br />如 果我们从设计的角度来看.一个项目中用若干个类需要去编写,由于这些类比较复杂,工作量比较大,这样每个类就需要占用一个工作人员进行编写.比如A程序员 去定Dog类,B程序员去写Cat类.这两个类本来没什么联系的,可是由于用户需要他们都实现一个关于"叫"的方法.这就要对他们进行一种约束.让他们都 继承于IBark接口,<span style="color: #0000ff"><strong>目的是方便统一管理.另一个是方便调用.当然了,不使用接口一样可以达到目的.只不过这样的话,这种约束就不那么明显,如果这样类还有Duck类等等,比较多的时候难免有人会漏掉这样方法.所以说还是通过接口更可靠一些,约束力更强一些.</strong></span><br /><br /><span style="color: #000000; background-color: #ffffff"><strong>2、</strong><a><strong><span style="color: #336699">C#中接口的深入浅出</span></strong></a><strong>:</strong></span></span></span></span></div> <p><br /><span style="font-size: small">通过学习对C#中接口的作用有了更进一步的理解，拿出来跟大家分享一下，有说的不对的地方请大家指教。<br /></span></p> <p><span style="font-size: small"><span style="color: #494949">&nbsp;&nbsp;&nbsp;   假设我们公司有两种程序员：VB程序员，指的是用VB写程序的程序员，用clsVBProgramer这个类表示；Delphi程序员指的是用 Delphi写程序的程序员，用clsDelphiProgramer这个类来表示。每个类都有一个WriteCode()方法。定义如下：</span> </span></p> <p><span style="font-size: small">class clsVBProgramer()<br />{<br />....<br />WriteCode()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp; //用VB语言写代码；<br />}<br />....<br />}</span></p> <p><span style="font-size: small">class clsDelphiProgramer()<br />{<br />....<br />WriteCode()<br />{<br />&nbsp;&nbsp;&nbsp; //用Delphi语言写代码；<br />}<br />&nbsp;&nbsp; ....<br />}</span></p> <p><span style="font-size: small">现在公司来了一个项目，要求派某个程序员写一个程序。<br />class clsProject()<br />{<br />....<br />WritePrograme(clsVBProgramer programer)//用VB写代码<br />{<br />&nbsp;&nbsp;&nbsp; programer.WriteCode();<br />}<br />WritePrograme(clsDelphiProgramer programer)//重载方法，用Delphi写代码<br />{<br />&nbsp;&nbsp;&nbsp; programer.WriteCode();<br />}<br />......<br />}<br />在主程序中我们可以这样写：<br />main()<br />{<br />&nbsp;&nbsp; clsProject proj=new clsProject;<br />&nbsp;&nbsp; //如果需要用VB写代码<br />&nbsp;&nbsp; clsVBProgramer programer1=new clsVBProgramer;<br />&nbsp;&nbsp; proj.WritePrograme(programer1);<br />&nbsp;&nbsp; //如果需要用Delphi写代码<br />&nbsp;&nbsp; clsDelphiProgramer programer2=new clsDelphiProgramer;<br />&nbsp;&nbsp; proj.WritePrograme(programer2);<br />}</span></p> <p><span style="font-size: small">但是如果这时公司又来了一个C#程序员，我们怎么 改这段程序，使它能够实现用C#写程序的功能呢？我们需要增加一个新类clsCSharpProgramer,同时在此clsProject这个类中要再 次重载WritePrograme（clsCSharpProgramer  programer）方法。这下麻烦多了。如果还有C程序员，C++程序员，JAVA程序员呢。麻烦大了！</span></p> <p><span style="font-size: small">但是如果改用接口，就完全不一样了：<br />首先声明一个程序员接口：<br />interface IProgramer()<br />{<br />WriteCode();<br />}<br />然后声明两个类，并实现IProgramer接口：<br />class clsVBProgramer():IProgramer<br />{<br />....<br />WriteCode()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp; //用VB语言写代码；<br />}<br />....<br />}</span></p> <p><span style="font-size: small">class clsDelphiProgramer():IProgramer<br />{<br />....<br />WriteCode()<br />{<br />&nbsp;&nbsp;&nbsp; //用Delphi语言写代码；<br />}<br />&nbsp;&nbsp; ....<br />}<br />对clsProject这个类进行一下修改：<br />class clsProject()<br />{<br />....<br />WritePrograme(IProgramer programer)<br />{<br />&nbsp;&nbsp;&nbsp; programer.WriteCode();//写代码<br />}<br />......<br />}</span></p> <p><span style="font-size: small">main()<br />{<br />&nbsp;&nbsp; clsProject proj=new clsProject;<br />&nbsp;&nbsp; IProgramer programer;<br />&nbsp;&nbsp; //如果需要用VB写代码<br />&nbsp;&nbsp; programer=new clsVBProgramer;<br />&nbsp;&nbsp; proj.WritePrograme(programer);<br />&nbsp;&nbsp; //如果需要用Delphi写代码<br />&nbsp;&nbsp; programer=new clsDelphiProgramer;<br />&nbsp;&nbsp; proj.WritePrograme(programer);&nbsp;&nbsp;&nbsp;<br />}<br />如果再有C#，C，C++，JAVA这样的程序员添加进来的话，我们只需把它们相关的类加进来，然后在main()中稍做修改就OK了。扩充性特别好！</span></p> <p><span style="font-size: small">另外我们如果把clsProject这个类封成一个组件，那么当我们的用户需要要扩充功能的时候，我们只需要在外部做很小的修改就能实现，可以说根本就用不着改动我们已经封好组件！是不是很方便，很强大！</span></p> </div><div id="MySignature">该文章经过本人整理所得,欢迎转载,转载时请加上本文地址;本文基于<a title="Creative Commons Attribution 2.5 China Mainland License" href="http://creativecommons.org/licenses/by/2.5/cn/" target="_blank">署名 2.5 中国大陆</a>许可协议发布，请勿演绎或用于商业目的，但是必须保留本文的署名<a href="http://www.cnblogs.com/zhangzt/">张志涛</a>（包含链接如您有任何疑问或者授权方面的协商，请<a href="http://space.cnblogs.com/msg/send/%E4%B8%8D%E6%82%94%E7%9A%84%E9%9D%92%E6%98%A5" target="_blank">给我留言</a>。 </div></div><img src ="http://www.cnitblog.com/stomic/aggbug/88463.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/stomic/" target="_blank">大话人生</a> 2013-08-26 17:09 <a href="http://www.cnitblog.com/stomic/archive/2013/08/26/88463.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>深入剖析ASP.NET的编译原理之二：预编译（Precompilation） （转）</title><link>http://www.cnitblog.com/stomic/archive/2010/11/10/71159.html</link><dc:creator>大话人生</dc:creator><author>大话人生</author><pubDate>Wed, 10 Nov 2010 11:50:00 GMT</pubDate><guid>http://www.cnitblog.com/stomic/archive/2010/11/10/71159.html</guid><wfw:comment>http://www.cnitblog.com/stomic/comments/71159.html</wfw:comment><comments>http://www.cnitblog.com/stomic/archive/2010/11/10/71159.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/stomic/comments/commentRss/71159.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/stomic/services/trackbacks/71159.html</trackback:ping><description><![CDATA[在本篇文章的第一部分:[原创]深入剖析ASP.NET的编译原理之一：动态编译（Dynamical
Compilation），详细讨论了ASP.NET如何进行动态编译的，现在我们来谈谈另外一种重要的编译方式：预编译
（Precompilation）。 <br>
<br>
<span class="B">1．为什么要进行预编译 <br>
</span><br>
ASP.NET
2.0的编译方式大体可以分成两种：动态编译和预编译，要回答为什么要进行预编译，我们先要看看动态编译有什么不好的地方。我们回顾一下上一篇介绍的
ASP.NET进行动态编译的简单的流程：当来自Brower的一个基于aspx的Http request抵达Web server，IIS
handle这个request，通过分析注册在IIS中的Application Mapping，将Request
传给aspnet_isapi.dll ISAPI extension。ISAPI extension通过HttpRuntime进入Http
Runtime
Pipeline，HttpRuntime为每个Request创建一个单独的HttpContext对象，用于保存request的Context信
息。在Http Runtime Pipeline中，Http request会被注册的一系列的Http
module处理，比如OutputCache Module，Session Module，Authentication
Module，AuthorizationErrorHandler
Module等等。在Pipeline的终端，ASP.NET需要需要根据request创建对应的HttpHandler对象来处理该Request，
并生成结果Response到Client。对于一个基于Aspx的Http request，对应的Http
handler对象一般就是一个System.Web.UI.Page对象。 <br>
<br>
ASP.NET会先判断对应的Page
type是否存在于被Cache的Assembly中，如果存在，直接创建Page对象，否则ASP.NET会先对该Page的相关的Source
code (包括code behind，html等等)
进行编译，我们也说过这种编译是一Directory为单位的，也就是说，处于同一个Directory下的需要编译的文件会被编译成到同一个
Assembly中。编译生成的Assembly会被Cache，用于后续的Request。 <br>
<br>
正是因为对资源的首次访问会导致一次编译（这样说不太准确，因为动态编译是以directory为单位进行的，应该对对某个Directory下的资源进
行首次访问），这样会严重降低Web Application的响应速度。所以我们为了避免这种情况，需要预先对web
site进行编译，所以提高web site的响应是进行预编译的最重要的原因。 <br>
<br>
同时动态编译就以为着Web server上放置的是Source code，而且他们是可被修改的。而对于一个开发完毕的Web
Application，我们更希望以Binary Assembly的方式进行部署，这样Server上部署的都是Binary
Assembly，不怕被别人篡改而导致系统的崩溃，从知识产权来讲，也更利于保护商业秘密。这也是我们为什么要进行预编译的另一个原因。 <br>
<br>
下面我们就来讲讲如何进行预编译，以及与编译背后的原理。同时在这里我需要特别提出的是，在上一部分讲的一些术语和原理，比如Preservation
file，FastObjectFactory，同样适用于预编译，重复的内容，在这里就不必再介绍了。同时我也将沿用上一部的Sample。如果想看看
相关的内容，请参阅[原创]深入剖析ASP.NET的编译原理之一：动态编译（Dynamical Compilation）。 <br>
<br>
<span class="B">2．In Place Pre-compilation V.S. Pre-compilation for
Deployment </span><br>
<br>
对于预编译，有可以分为In Place Pre-compilation和Pre-compilation for Deployment，In
Place Pre-compilation很简单，实际上就是把整个Web
site编译到我们一个临时的目录下面，这个临时目录也就是我们在介绍动态编译提到的那个临时目录。而且这个编译的方式，包括生成的文件也和动态编译完全
一样，唯一不同就是编译的时间：预先编译，编译的范围：整个Web site。这种编译就是你常用的在VS的build。这种编译方式一般用于开发阶段。
<br>
<br>
为了部署为目的的编译是我们今天讨论的重点，下面我们就着重来讨论Pre-compilation for Deployment。 <br>
<br>
注：在ASP.NET的编译都是通过一个叫做aspnet_compiler的工具执行的，该工具随ASP.NET
2.0一起发布，你完全可以利用此工具以命令行的方式的执行编译，并通过传递不同的命令行开关设置不同的编译选项。该工具被置于了VS中，使你可以利用
VS进行可视化的编译。 <br>
<br>
<span class="B">3．Non-updatable Pre-compilation V.S. Updatable
Pre-compilation </span><br>
<br>
ASP.NET 2.0为我们提供了几种不同方式的预编译和部署。为了弄清楚这些预编译和部署方式，我们先来回顾一下ASP.NET
1.x下的编译方式。我们知道在ASP.NET 1.x时代对整个Web
site进行编译，实际上我们只会对所有C#和VB.NET等后台代码进行编译，并生成一个单一的Assembly。而Web
page的aspx是不会参与编译的。所以当我们访问一个Web page的时候，ASP.NET必须对aspx进行动态编译。 <br>
<br>
这一切之所以能够进行是因为Web page采用的是aspx + code behind的模式。 <br>
<br>
<div class="Code">&lt;%@ Page Language="C#" AutoEventWireup="false"&nbsp;
Codebehind="Default.aspx.cs"&nbsp; Inherits="Default" %&gt;</div>
<br>
<div class="Code">
<p>public partial class Default : System.Web.UI.Page<br>
{&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp;&nbsp; protected void Page_Load(object sender, EventArgs e)&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; }<br>
}</p>
</div>
<p>从上面我们可以看到aspx和Code behind是一种继承的关系，aspx继承和它对应的Code
Behind。ASP.NET可以把Code
behind和aspx分开进行编译，把它们编译到不同的Assembly中。我们就是上面的Code为例，我们现在若对该Web
site进行编译的话，Default.aspx.cs会被编译到一个Assembly中，假设这个Assembly为App_Web.dll.
我们把该Dll和aspx部署到Production
Server上。如果我们现在访问defaut.aspx。ASP.NET会对aspx进行动态编译，生成的Assembly可以暂时成为
App_Web_aspx.dll。对于Default.aspx，如果我们如C#代码来描述的话，应该像下面一样定义： </p>
<div class="Code">public class default_aspx:Default<br>
{&nbsp;&nbsp; <br>
}</div>
<p>这种编译方式，我自己把它叫做对asXx的动态编译。在ASP.NET2.0 中也沿用了这种编译方式。这种编译方式的主要特征是对Code
behind和所有的后台代码进行预编余，aspx（确切地说应该是asXx：asax，asmx，asax等）原样部署。由于这种方式的预编
译，asXx是可以修改的（当然这种修改是有一定限制的，因为code behind已经编译好了，所以这种修改只可能是和code
behind无关的修改），所以又叫做Updatable Pre-compilation。 <br>
<br>
除了Updatable Pre-compilation之外，ASP.NET还提供另外一种高效的预编译方式，Non-updatable
Pre-compilation，之所以叫做不可修改的预编译，这是因为：这种编译方式把asXx、Code
behind、后台代码甚至是部分Resource都进行预编译，从而避免了运行时对asXx的动态编译，从而最大程度地提高了整个Web
site的响应。在部署的时候，我们除了把生成的Assembly进行部署之外，所有的通过编译生成的asXx也必须进行部署。
不过需要特别说明的是，此时的asXx文件仅仅是一个占位的文件而已，它里面不具有任何HTML。 <br>
<br>
<span class="B">4．Partial class </span><br>
<br>
在ASP.NET 1.x，由于采用的aspx + code behind的机制，对于任何一个Web page或者其他ASP.NET
基于axXx的对象来说，都是由两个文件、两个class组成。两个文件是指axXx和code behind，两个class是指Code
behind定义的继承自System.Web.UI.Page的class，和一个继承自它的由axXx生成的class。 <br>
<br>
对于使用过ASP.NET 1.x来说，一定会很熟悉这样一种情况：对于每个在aspx中通过HTML定义的Server Control，在Code
behind中必须具有一个对应的protected成员，否则你不能通过编程的方式访问这个Server
control。以不同方式呈现的同一个Server control通过ID关联起来，如果在Code behind中改了Server
control的ID，Server control的Server端的Event handler将会失去原有的作用。 <br>
<br>
但是在ASP.NET 2.0来说，这种情况发生了改变，在aspx中的Server control在Code
behind中却没有相应的成员变量，但是我们可以毫无障碍地访问到每个Server control。这使得我们的code
behind更加简洁，通过避免了Server control在aspx和code bebind中的不匹配的问题。这一切都得益于.NET
Framework 2.0提供的partial
class的机制：把同一个class分布于不同文件中进行定义。有了这个概念，我们来看ASP.NET 2.0的code behind机制。 <br>
<br>
比如我们有这样的一个Page： </p>
<div class="Code">&lt;%@ Page Language="C#" AutoEventWireup="true"
CodeFile="Default.aspx.cs" Inherits="_Default" %&gt;<br>
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;<br>
&lt;html xmlns="http://www.w3.org/1999/xhtml" &gt;<br>
&lt;head runat="server"&gt;<br>
&nbsp;&nbsp;&nbsp; &lt;title&gt;Default&lt;/title&gt;<br>
&nbsp;&nbsp;&nbsp; &lt;link href="Style.css" rel="stylesheet" type="text/css" /&gt;&nbsp; <br>
&lt;/head&gt;<br>
&lt;body&gt;<br>
&nbsp;&nbsp;&nbsp; &lt;form id="form1" runat="server"&gt;&nbsp; <br>
&nbsp;&nbsp;&nbsp; &lt;div&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;asp:Button runat="server" ID="btnRefresh" Text="Refresh"
OnClick="btnRefresh_Click" /&gt;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; &lt;/div&gt;<br>
&nbsp;&nbsp;&nbsp; &lt;/form&gt;<br>
&lt;/body&gt;<br>
&lt;/html&gt;</div>
<p>Code behind如下： </p>
<div class="Code">public partial class _Default : System.Web.UI.Page<br>
{<br>
&nbsp;&nbsp;&nbsp; protected void Page_Load(object sender, EventArgs e)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; protected void btnRefresh_Click(object sender, EventArgs e)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.Response.Write("The click event of \"Refresh\" button is
fired");<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>而实际上，ASP.NET会为我们创建一个隐藏的.cs文件（这个文件有人 把它称之为Sibling partial class）：
<div class="Code">public partial class _Default: IRequiresSessionState<br>
{<br>
&nbsp;&nbsp;&nbsp; protected Button&nbsp; _ btnRefresh;<br>
}</div>
<p>这个文件会随着aspx文件的改变而动态变化，所以code behind中的Server control永远和aspx中的Server
control是完全匹配的。所以我们说ASP.NET 2.0的Page是由3个文件、两个class组成的。 <br>
<br>
<span class="B">5．编译的粒度和Assembly的命名 </span><br>
<br>
到现在为止，我们所讲的ASP.NET的预编译都是以Directory为单位的，同一个Directory下的所有需要编译的文件被编译到同一个
Assembly中。ASP.NET还支持以Page为单位的预编译，也就是每个Page编译成一个Assembly。 <br>
<br>
在默认的情况下，ASP.NET预编译生成的Assembly名称是随机生成的，也就是每次生成的Assembly都具有不同的name。所以我们在部署
Web
site的时候，一般需要把原来的Assembly删掉，再部署新的Assembly。不过ASP.NET为我们提供了另外一种选择，使得每次编译生成的
Assembly具有相同的名称，这样我们部署的时候就可以直接把新的Assembly　拷贝到Production
Server上，自动覆盖掉同名的Assembly。 <br>
<br>
<span class="B">6． Sample </span><br>
<br>
我们沿用上一部份是用的Sample，我们通过采用不同的预编译方式看看程序将如何运行。 <br>
<br>
<span class="B"><font color="#0000ff">6.1 Non-updatable Pre-compilation</font>
</span><br>
<img  src="http://www.sosuo8.com/article/upimages2/precompilation_02_01.jpg" alt=""><br>
<br>
我们采用如上图所示的默认的发布方式，ASP.NET 将会进行Non-updatable
Pre-compilation。浏览目标文件夹，我们会发现如下的文件结构. </p>
<p><img  src="http://www.sosuo8.com/article/upimages2/precompilation_02_02.jpg" alt="" width="561" height="190"><br>
<br>
除了多了一个Bin目录和PrecompiledApp.config之外，整个结构和Source
code中的结构完全一样。通过上面的分析，我们知道这种预编译方式是将asXx、code
behind、后台代码已经Resource一起编译成Assembly。我们说过对于这样的预编译方式，aspx仅仅是一个站位的文件而以，其中
HTML已经没有任何意义了，那么对于编译后的aspx中到底是什么东西呢。我们来一探究竟。打开每个aspx都是一段如下如下一样文字，并无任何
HTML。 </p>
<div class="Code">This is a marker file generated by the precompilation
tool, and should not be deleted!</div>
<p>PrecompiledApp.config里面具有一段简短的configuration，表明version和是否可以进行进一步的修改。 </p>
<div class="Code">&lt;precompiledApp version="2" updatable="false"/&gt;</div>
<p>所有的Assembly被编译到Bin目录中，我们来看看到底生成了一些什么样的文件在Bin目录中。</p>
<p><img  src="http://www.sosuo8.com/article/upimages2/precompilation_02_03.jpg" style="width: 651px; height: 271px;" alt="" width="616" height="271"></p>
<p>在Bin目录由两类文件构成：Assembly和以complied作为扩展名的Preservation file。Preservation
file的内容和作用在第一部分已经详细介绍过了，相信大家不会感到陌生。Preservation
file在这里和动态编译所起的作用一样。唯一有一点不同的是，他的结构更加简洁，去掉的Dependence
file的列表，因为对于Non-updatable Pre-compilation来说，每个Page的以来的文件都是不可更改的。 </p>
<div class="Code">&lt;preserve resultType="6"
virtualPath="/Artech.ASPNETDeployment/App_Code/" hash="439abe7d"
filehash="" flags="140000" assembly="App_Code" /&gt;</div>
<p>我们来运行以下程序，和动态编译情况下的输出结果比较，看看有什么不同。我们照例先运行Default Page。 <br>
<img  src="http://www.sosuo8.com/article/upimages2/precompilation_02_04.jpg" alt="" width="504" height="152"></p>
<p>输出的结果印证我们前面的讨论：处于同一个目录下的Default
和Default2被编译到同一个Assembly中，关注于处理逻辑的code behind的class
name为Default和Default2，关注与可视化界面render的aspx对应的class
name被加上的_aspx后缀，如果对default_aspx和default2_aspx进行Reflect的话，你会发现他们分别继承
Default和Default2，而后者直接继承自System.Web.UI.Page。所以default_aspx和default2_aspx
是真正的意义上基于Web page的Http
handler。像动态编译一样，预编译生成一个基于Assembly的FastObjectFactory Type，对该对象的描述请参照第一部分。
<br>
<br>
有了前面的理论基础，相信大家已经猜到这时候，我浏览Part I下的Page1和Page2时的输出是什么
样子，由于预编译是以目录为单位的，我们对Part
I下的任何一个page的访问，都会加载相同的Assembly，所以此时对这两个Page的访问会得到一样的输出结果： <br>
<br>
<img  src="http://www.sosuo8.com/article/upimages2/precompilation_02_05.jpg" alt="" width="500" height="182"></p>
<div class="content_middle">
<p><span class="B">6.2 Updatable Pre-compilation </span><br>
<br>
接下来我们来对Web Page进行Updatable Pre-compilation,相关的编译设置如下：选择Allow this
precompiled site to be updatable。 <br>
<br>
<img  src="http://www.sosuo8.com/article/upimages2/precompilation_02_12.jpg" alt="" width="606" height="397"></p>
<p>生成的文件及其结构和进行Non-updatable Pre-compilation，不同的又一下3点： <br>
<br>
1、PrecompiledApp.config：updatable被设置为true。 </p>
<div class="Code">&lt;precompiledApp version="2" updatable="true"/&gt;</div>
<p>2、asXx和我们进行开发时内容一样，你如aspx包含的就是HTML，我们可以在部署之后对他们进行和code behind无关的修改。 <br>
<br>
3、Preversation file中有加上了Page对应的dependence file列表。 </p>
<div class="Code">&lt;?xml version="1.0" encoding="utf-8"?&gt; <br>
&lt;preserve resultType="9"
virtualPath="/Artech.ASPNETDeployment/App_GlobalResources/"
hash="439abe7d" filehash="ff21249472dbf6cb" flags="140000"
assembly="App_GlobalResources" resHash="1cba48dd56e28538" /&gt; </div>
<p>我们来运行一下Web site，看看现在的输出结果又有何不同。首先打开Default Page： <br>
<br>
<img  src="http://www.sosuo8.com/article/upimages2/precompilation_02_06.jpg" alt=""><br>
<br>
通过上图，我们发现此时加载了两个相关的Assembly。我们来分析一下为什么会这样。在分析Updatable
Pre-compilation时，我们说过：asXx是不会才与编译的，只有他们的code behind,
所有的后台代码，资源文件才会本编译。对于一个page 来说，page的code
behind被编译到Assembly中，aspx则不会。Aspx在运行时实行动态编译，所以aspx是可被修改的。在本例中，我们访问Default
Page，ASP.NET先对aspx进行编译，其对应的class
name为default_aspx，由于default_aspx继承与Default，并且Default存在于预编译生成的Assembly中，所
以这个Assembly被加载进来。 <br>
<br>
由于同一个page最重本编译到两个不同的Assembly中，所以我们此时访问Part
I中的Page1或者Page2，又会有两个Assembly被加载进来： <br>
<br>
<img  src="http://www.sosuo8.com/article/upimages2/precompilation_02_07.jpg" alt=""></p>
<p><span class="B">6.3 以Page为单位进行预编译 </span><br>
<br>
前面我们进行的都是以directory为单位的预编译，现在我们缩小编译的粒度，以Page为单位进行编译。我们选择了&#8220;Use fixed
naming and single page assemblies&#8221;选项。那么现在进行的是 基于单个page的non-updatable
pre-compilation。通时由于采用的是fixed naming的编译方式，每次进行编译生成的Assembly的名称都是一样的。 <br>
<br>
<img  src="http://www.sosuo8.com/article/upimages2/precompilation_02_13.jpg" alt=""></p>
<p>现在我们来看看，编译之后生成的Assembly： <br>
<img  src="http://www.sosuo8.com/article/upimages2/precompilation_02_08.jpg" alt=""></p>
<p>我们看到编译器为每个Page生成了一个单独的Assembly。此时运行程序，你看到的又将不同。如果此时你访问Default
Page，你将看到： <br>
<br>
<img  src="http://www.sosuo8.com/article/upimages2/precompilation_02_09.jpg" alt="" width="579" height="117"></p>
<p>是不是和上面不同，Assembly只有Default对应的两个Type，没有了处于同一个目录下的Default2的Type。因为
Default2有它独自的Assembly
.所以你该会想到，如果我们现在每访问一个没有被访问过的Page，就会有一个新的Assembly被加载。比如我么访问Part I下的Page1： <br>
<br>
<img  src="http://www.sosuo8.com/article/upimages2/precompilation_02_10.jpg" alt="" width="599" height="145"></p>
<p><span class="B">6.4编译强类型的Assembly </span><br>
<br>
我们知道可以通过一个Public key/Private key pair对Assembly进行签名，进而把它部署到GAC中，我们来看看如何做。
<br>
<br>
首先我通过SN.exe生成Public key/Private key
pair并保存到一个文件中（比如D:\MyKey.keys），然后进行如下的编译设置 </p>
<p><img  src="http://www.sosuo8.com/article/upimages2/precompilation_02_14.jpg" alt=""></p>
<p>那么我们进行编译就会生成强类型的Assembly。我们可以运行我们的程序来证明： <br>
<br>
<img  src="http://www.sosuo8.com/article/upimages2/precompilation_02_11.jpg" style="width: 632px; height: 150px;" alt="" width="674" height="150"><br>
<br>
每个Assembly有具有一样的PublicKeyToken，因为我们使用的一样的Public key/Private key
pair进行对每个Assembly签名的。
</p>
</div>
<p>
</p>
<br></div><img src ="http://www.cnitblog.com/stomic/aggbug/71159.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/stomic/" target="_blank">大话人生</a> 2010-11-10 19:50 <a href="http://www.cnitblog.com/stomic/archive/2010/11/10/71159.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>深入剖析ASP.NET的编译原理之一：动态编译（Dynamical Compilation）（转）</title><link>http://www.cnitblog.com/stomic/archive/2010/11/10/71157.html</link><dc:creator>大话人生</dc:creator><author>大话人生</author><pubDate>Wed, 10 Nov 2010 09:13:00 GMT</pubDate><guid>http://www.cnitblog.com/stomic/archive/2010/11/10/71157.html</guid><wfw:comment>http://www.cnitblog.com/stomic/comments/71157.html</wfw:comment><comments>http://www.cnitblog.com/stomic/archive/2010/11/10/71157.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/stomic/comments/commentRss/71157.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/stomic/services/trackbacks/71157.html</trackback:ping><description><![CDATA[<div class="content_middle">
<p>Microsoft 的Visual Studio为我们在应用开发中提供的强大功能，我们是有目共睹。借助该工具，是我们的开发
显得更加高效而轻松。从Microsoft把这个IDE的名字从VS.NET 该为VS（比如原来的Visual Studio.NET
2003，现在的版本叫VS2005），可以MS对该IDE的期望和野心：MS要把它改造成一个万能的IDE。不过任何都有其两面性，对于我们广大的开发
者来说，VS是我们的各种行为简单化，傻瓜化；但是在另一方面，他也会蒙蔽我们的眼睛，使我们对它背后做的事情视而不见。以我们的ASP.NET
Website开发为例，编程、编译、部署都可以借助VS，有了VS一切显得如此简单，每个人都会做，但是我想很多一部分人对一个ASP.NET
Website如何进行编译不会很了解。这篇文章就来谈谈背后的故事——ASP.NET是如何进行编译的。由于篇幅的问题整篇文章分两个部分：动态编译
Dynamical Compilation和预编译（Precompilation）。 <br>
<br>
<span class="B">1．动态编译的过程 </span><br>
<br>
我们先来介绍在动态编译下的大体的执行流程：当ASP.NET收到一个基于某个page的request的时候，先判断该Page和相关的Source
code是否编译过，如果没有就将其编译，如果已经编译，就是用已经Load的Assembly直接生成Page对象。 <br>
<br>
<span class="B"><font color="#ff0000">在这里有下面几点需要注意：</font> </span><br>
<br>
1)． 动态编译是按需编译的，ASP.NET只会编译和当前Request相关的aspx和code。 <br>
<br>
2)． 动态编译是基于某个目录的，也就是说ASP.NET会把被请求的page所在的目录的所有需要编译的文件进行编译，并生成一个Assembly。
<br>
<br>
3)． 除了编译生成的Assembly外，动态编译还会生成一系列的辅助文件。 <br>
<br>
4)．
对相关文件的修改，会导致重新编译，但是修改对当前的Request不起作用。也就是说如果你对某个aspx进行修改，那么对于修改后抵达的
Request，会导致重新编译，但是对于之前的Request使用的依然是原来编译好的Assembly。 <br>
<br>
5)． 编译生成的文件被放在一个临时目录中，这个目录的地址为Windows
Directory\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET
Files。其具体的目录结构如下图所示： <br>
<br>
<img  src="http://www.sosuo8.com/article/upimages2/precompilation_01_05.jpg" alt=""></p>
<p>在Temporary ASP.NET Files下的Artech.ASPNETDeployment是IIS中Virtual
Directory的名称，以下两级目录的名称由Hash
value构成，所以编译生成的文件就保存在c6f16246目录下。这个目录你可以通过HttpRuntime.CodegenDir获得。 <br>
<br>
Directory\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET
Files只是一个默认的临时目录，你可以在web config中的compilation section中设置你需要的临时目录。 </p>
<div class="Code">&lt;compilation tempDirectory="d:\MyTempFiles" /&gt;</div>
<p><span class="B">2．Sample </span><br>
<br>
现在我用一个Sample来一探ASP.NET是如何进行动态编译的。 </p>
<p><img  src="http://www.sosuo8.com/article/upimages2/precompilation_01_01.jpg" alt=""></p>
<div class="content_middle">
<p>在这个Sample中，我建立了一个Website，在根目录下创建了两个Page：Default和Default2。 <br>
<br>
在两个子目录Part I和Part II下分别创建了两个Web
page:Page1和Page2。在App_Code目录中创建了一个Utility的static class。下面是它的定义： </p>
<div class="Code">
<p>public static class Utility<br>
{<br>
&nbsp;&nbsp;&nbsp; public static string ReflectAllAssmebly()<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StringBuilder refllectionResult = new StringBuilder();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach (Assembly assembly in
AppDomain.CurrentDomain.GetAssemblies())<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(!assembly.FullName.Contains("App_Web"))<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; refllectionResult.Append(assembly.FullName +
"&lt;br/&gt;");<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Type[] allType = assembly.GetTypes();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach (Type typeInfo in allType)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
refllectionResult.Append("&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"+
typeInfo.Name + "&lt;br/&gt;");<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return refllectionResult.ToString();<br>
&nbsp;&nbsp;&nbsp; }<br>
}</p>
</div>
<p>内容很简单，对当前加载的所有相关的Assembly（这些Assembly的Fullname以App_Web打头）进行Reflection，
列出所有的Type。这个ReflectAllAssmebly将在5个Web page（Default
Page和两队Page1&amp;Page2）的Page_Load事件中被调用。 </p>
<div class="Code">protected void Page_Load(object sender, EventArgs e)<br>
{<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.Response.Write(Utility.ReflectAllAssmebly());<br>
}</div>
<p>Default是列出所有4Page对应的Link以便我们访问它们，在我们再进行编译的情况下在IE中输入对应的URL来访问Default
Page。(其他Page的Html中不具有真正的内容，是一个空的page.) <br>
<br>
<img  src="http://www.sosuo8.com/article/upimages2/precompilation_01_02.jpg" alt="" width="549" height="150"></p>
<p>通过上面的显示，我们可以看到现在有一个Assembly：App_Web_wh7-uda5。该Asssembly定一个的Type有5个，
_Default和 default_aspx分别对应Default Page，而Default2和 default2_aspxDefault2
Page的。FastObjectFactory_app_web_wh7_uda5是很重要的Type，我将会在后面对其进行深入介绍。正如我们在上面
说过的，动态编译是按需编译，现在我们对Default Page进行访问，由于这次对该Website的第一次访问，所有需要的Source
Code，包括aspx，code behind都要进行编译。在这个Sample中，虽然我们并没有访问Default2
page，但是我们说过，动态编译是基于目录的，由于Default Page和Default2
Page都直接置于根目录下，所以ASP.NET会把根目录下的所有文件编译到一个Assembly中。由于Page1和Page2位于子目录Part
I和Part II之下，所以不会参与编译。除非我们下载对它进行Request。 <br>
<br>
我们现在来访问Part I下的Page1和Page2看看会有什么结果。我们会发现，两次Request获得的输出是一样的： <br>
<img  src="http://www.sosuo8.com/article/upimages2/precompilation_01_03.jpg" alt=""><br>
<br>
通过上面的输出我们发现，当前AppDomain中被加载的Assembly多了一个：App_Web_n1mhegpg。我们可以通过定义在该
Assembly中的Type的命名可以猜出该Assembly是对Part I 目录进行编译产生的。Page1和Page2的编译后的Type
name变成了part_i_page1_aspx&amp; Page1和part_i_page2_aspx&amp;
Page2。此外我们看到，该Assembly中依然有一个FastObjectFactory的
Type：FastObjectFactory_app_web_n1mhegpg。在这里我需要特别指出的是，名称的后缀都是通过
Hash算法得到的。 <br></p>
<p>有了上面的理论和实验结果，我想这个时候，你肯定已经想到，如果我现在对Part II的Page1和Page2进行访问，输出结果会是什么样子了。 <br>
<img  src="http://www.sosuo8.com/article/upimages2/precompilation_01_04.jpg" alt=""><br>
<br>
如果这个时候，你查看临时目录（Directory\Microsoft.NET\Framework\v2.0.50727\Temporary
ASP.NET Files）中该Website对应的子目录，已将会看到生成了一些列的文件。 <br>
<br>
<span class="B">3．Page最终被转化成什么？ <br>
</span><br>
我们现在来看看通过编译，一个Page到底转换成什么。我们以Part
I/Page1为例。通过上面的Sampe，我们知道它最终变成了两个Type：Page1和part_i_page1_aspx。 <br>
<br>
下面是Page1的定义：
</p>
<div class="Code">
<p>public class Page1 : Page, IRequiresSessionState<br>
{&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; // Fields&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; protected HtmlForm form1;&nbsp;&nbsp;&nbsp; </p>
<p>&nbsp;&nbsp;&nbsp; // Methods&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; protected void Page_Load(object sender, EventArgs e)&nbsp;&nbsp;&nbsp; ]<br>
&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; base.Response.Write(Utility.ReflectAllAssmebly());&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; }&nbsp; </p>
<p>&nbsp;&nbsp; // Properties&nbsp;&nbsp; <br>
&nbsp;&nbsp; protected HttpApplication ApplicationInstance&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return this.Context.ApplicationInstance;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; </p>
<p>&nbsp;&nbsp;&nbsp; protected DefaultProfile Profile&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (DefaultProfile) this.Context.Profile;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <br>
&nbsp; }<br>
}</p>
</div>
<p>下面是part_i_page1_aspx的定义 </p>
<div class="Code">
<p>[CompilerGlobalScope]<br>
public class part_i_page1_aspx : Page1, IHttpHandler<br>
{<br>
&nbsp;&nbsp;&nbsp; // Fields<br>
&nbsp;&nbsp;&nbsp; private static object __fileDependencies;<br>
&nbsp;&nbsp;&nbsp; private static bool __initialized;</p>
<p>&nbsp;&nbsp;&nbsp; // Methods<br>
&nbsp;&nbsp;&nbsp; public part_i_page1_aspx();<br>
&nbsp;&nbsp;&nbsp; private HtmlHead __BuildControl__control2();<br>
&nbsp;&nbsp;&nbsp; private HtmlTitle __BuildControl__control3();<br>
&nbsp;&nbsp;&nbsp; private HtmlLink __BuildControl__control4();<br>
&nbsp;&nbsp;&nbsp; private HtmlForm __BuildControlform1();<br>
&nbsp;&nbsp;&nbsp; private void __BuildControlTree(part_i_page1_aspx __ctrl);<br>
&nbsp;&nbsp;&nbsp; protected override void FrameworkInitialize();<br>
&nbsp;&nbsp;&nbsp; public override int GetTypeHashCode();<br>
&nbsp;&nbsp;&nbsp; public override void ProcessRequest(HttpContext context);<br>
}</p>
</div>
<p>在part_i_page1_aspx中定义了一个基于aspx的HttpHandler所需的所有操作，并且它继承了Page1。所以我们可以说
Part I/Page1这个page 最终的体现为part_i_page1_aspx。进一步说，对Part I/Page1的Http
Request，ASP.NET所要做的就是生成一个part_i_page1_aspx来Handle这个request就可以了。 <br></p>
<p><span class="B">4．FastObjectFactory </span><br>
<br>
通过上面的一个简单的Sample，你已经看到每个Assembly中都会生成一个以FastObjectFactory作为前缀的Type。这是一个很
重要的Type，从它的名称我们不难猜出它的作用：高效的生成对象。而生成的是什么样的对象呢？实际上就是基于每个aspx的Http
request的Http handler，对于Part I/Page1就是我们上面一节分析的part_i_page1_aspx对象。 <br>
<br>
我们现在通过Reflector查看我们生成的App_Web_n1mhegpg中的
FastObjectFactory_app_web_n1mhegpg是如何定义的。
</p>
<div class="Code">
<p>internal class FastObjectFactory_app_web_n1mhegpg<br>
{<br>
&nbsp;&nbsp;&nbsp; // Methods<br>
Private FastObjectFactory_app_web_n1mhegpg()<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; private static object Create_ASP_part_i_page1_aspx()<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new part_i_page1_aspx();<br>
&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; private static object Create_ASP_part_i_page2_aspx()<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new part_i_page2_aspx();<br>
&nbsp;&nbsp;&nbsp; }<br>
}</p>
</div>
<p>通过上面的Code，我们可以看到在FastObjectFactory中定义一系列的Create_ASP_XXX(后缀就是Page
编译生成的Type的名称)。通过这些方法，可以快速生成对一个的Page。至于为什么会叫作FastObjectFactory，我想是因为直接通过调
用这个静态的方法快速地创建Page对象，从而避免使用Reflection的late binding带来的性能的影响吧。 <br>
<br>
<span class="B">5．Preservation Files </span><br>
<br>
进行每一次编译，ASP.NET会生成一系列具有.compiled扩展名的保留文件（Preservation
File）。这个文件非常重要，我们现在来深入介绍这个样一个文件。 <br>
<br>
Preservation File这个文件本质上是一个XML。它是基于每个Page的，也就是每个Page都会有一个这样的Preservation
File. 无论Page对应的Directory是怎样的，与之对应的Preservation
File总会保存在根目录下，所以必须有一种机制保持为处于不同Directory的Page生成的Preservation
File具有不同的文件名，不管Page的名称是否一样。所以Preservation File采用下面的命名机制： <br>
<br>
[ page ].aspx.[folder-hash].compiled <br>
<br>
其中[ page ]是Page的名称，[folder-hash]是对page所在路径的Hash Value。这样做有两个好处。 <br>
<br>
1、保证处于同一级目录的所有Preservation File具有不同的文件名。 <br>
2、保证ASP.NET对于一个Http request可以找到Page对应的Preservation File。 <br>
<br>
下面这个Preservation File就是上面Sample中Part II/Page1.aspx对应的Preservation
File，名称为</p>
<div class="Code">default2.aspx.cdcab7d2.compiled。我们来看看XML每个Item各代表什么意
思。&nbsp;<br>
&lt;?xml version="1.0" encoding="utf-8"?&gt;<br>
&lt;preserve resultType="3" virtualPath="/Artech.ASPNETDeployment/Part
II/Page1.aspx" hash="fffffff75090c769" filehash="5f27fa390c45c52a"
flags="110000" assembly="App_Web_hitlo3dt"
type="ASP.part_ii_page1_aspx"&gt;<br>
&nbsp;&nbsp;&nbsp; &lt;filedeps&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filedep name="/Artech.ASPNETDeployment/Part II/Page1.aspx"
/&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filedep name="/Artech.ASPNETDeployment/Part
II/Page1.aspx.cs" /&gt;<br>
&nbsp;&nbsp;&nbsp; &lt;/filedeps&gt;<br>
&lt;/preserve&gt;</div>
有这段XML我们可以看到，所有的内容都包含在preserve XML element中，在他中间定义了几个重要的attribute. <br>
<br>
1、virtualPath: Page的虚拟地址。 <br>
2、assembly：Assembly名称 <br>
3、Type：Page的编译后对应的Type（Http handler）。 <br>
4、hash: 一个代表本Preservation File状态的Hash value。 <br>
5、filehash: 一个代表本Dependent File状态的Hash value。 <br>
<br>
通过hash和filehash的缓存，ASP.NET可以判断自上一次使用以来，Preservation File和它所依赖的Dependent
File是否被改动，如果真的被改动，将会重新编译。因为对于文件的任何改动都会导致该Hash value的改变。 <br>
<br>
此外，Preservation File的&lt;filedeps&gt;列出了所有依赖的文件，对于Page,一般是aspx和code
behind。 <br>
<span class="B"><br>
6. 进一步剖析整个动态编译过程 </span><br>
<br>
现在我们来总结整个动态编译的过程： <br>
<br>
Step1：当ASP.NET收到对于某个Page的Request，根据这个request对应的Url试着找到该page对应的
Preservation
File，如果没有找到，重新编译Page所在目录下的所有需要编译的文件，同时生成一些额外的文件，包括Preservation File。 <br>
<br>
Step2：然后解析这个Preservation File，通过hash和filehash判断文件自身或者是Dependent
File是否在上一次编译之后进行过任何的修改，如果是的，则重新编译。然后重新执行Step2。 <br>
<br>
Step3：通过Preservation File 的assembly attribute
Load对应的assembly(如果Assembly还没有被Load的话)，通过type获知对应的aspx
type，然后借助FastObjectFactory的对应的Create_ASP_XXX创建这个type。这个新创建的对象就是我们需要的Http
Handler，在之上执行相应的操作把结果Response到客户端。 <br>
<br>
对动态编译的讨论就到这里，在本篇文章下半部分将会讨论另一种更加有用的编译方式</div>
<p>
</p>
</div><img src ="http://www.cnitblog.com/stomic/aggbug/71157.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/stomic/" target="_blank">大话人生</a> 2010-11-10 17:13 <a href="http://www.cnitblog.com/stomic/archive/2010/11/10/71157.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>编译型语言VS解释型语言</title><link>http://www.cnitblog.com/stomic/archive/2010/11/10/71156.html</link><dc:creator>大话人生</dc:creator><author>大话人生</author><pubDate>Wed, 10 Nov 2010 08:50:00 GMT</pubDate><guid>http://www.cnitblog.com/stomic/archive/2010/11/10/71156.html</guid><wfw:comment>http://www.cnitblog.com/stomic/comments/71156.html</wfw:comment><comments>http://www.cnitblog.com/stomic/archive/2010/11/10/71156.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/stomic/comments/commentRss/71156.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/stomic/services/trackbacks/71156.html</trackback:ping><description><![CDATA[<div style="margin: 0cm 0cm 0pt;" class="MsoNormal"><font size="2"><span>将
高级语言翻译成机器语言有两种方式：编译和解释。二者区别在于翻译的时间不同。</span></font></div>
<div style="margin: 0cm 0cm 0pt;" class="MsoNormal">
<p><font size="2"><span><strong>编译型语言：</strong>程序在执行之前需要一个专门的编译过程，把程序编译成
为机器语言的文件，运行时不需要重新翻译，直接使用编译的结果就行了。程序执行效率高，依赖编译器，跨平台性差些。如C、C++、Delphi等</span></font></p>
<p><font size="2"><span><strong>解释型语言：</strong>程序不需要编译，程序在运行时才翻译成机器语言，每执
行一次都要翻译一次。因此效率比较低。比如</span><span>Basic</span><span>语言，专门有一个解释器能够直接执行</span><span>Basic</span><span>程
序，每个语句都是执行的时候才翻译。(在运行程序的时候才翻译，专门有一个解释器去进行翻译，每个语句都是执行的时候才翻译。效率比较低，依赖解释器，跨
平台性好.)</span></font></p>
</div>
<div style="margin: 0cm 0cm 0pt;" class="MsoNormal"> </div>
<div style="margin: 0cm 0cm 0pt;" class="MsoNormal"><font size="2"><span>C</span><span>语
言是编译型的。</span></font></div>
<div style="margin: 0cm 0cm 0pt;" class="MsoNormal"><font size="2"><span>Java
比较</span><span>特殊，</span><span>Java</span><span>程序也需要编译，但是没有直接编译成机器语言，而是
编译成字节码，然后用解释方式执行字节码。</span></font></div>
<div style="margin: 0cm 0cm 0pt;" class="MsoNormal"><font size="2"><span>C
程序</span><span>——</span><span>&gt;</span><span>机器语言（编译）</span></font></div>
<p><font size="2"><span>Java程序</span><span>——</span><span>&gt;</span><span>字
节码（编译）——</span><span>&gt;</span><span>机器语言（解释）</span></font></p>
<p><font size="2"><span><strong><font size="3">脚本语言</font></strong>介于
HTML和C,C++,Java,C#等编程语言之间。 <br>
HTML通常用于格式化和链结文本。而编程语言通常用于向机器发出一系列复杂的指令。 <br>
脚本语言与编程语言也有很多相似地方，其函数与编程语言比较相象一些，其也涉及到变量。与编程语言之间最大的区别是编程语言的语法和规则更为严格和复杂一
些. <br>
脚本与程序代码的关系：脚本也是一种语言，其同样由程序代码组成。
注：脚本语言一般都有相应的脚本引擎来解释执行。他们一般需要解释器才能运行。JAVASCRIPT、ASP、PHP、PERL都是脚本语言。C/C++
编译、链接后，可形成独立执行的exe文件。 <br>
脚本语言是一种解释性的语言，例如vbscript、javascript、installshield
script等等，它不象c\c++等可以编译成二进制代码，以可执行文件的形式存在。<br>
脚本语言不需要编译，可以直接用，由解释器来负责解释。 <br>
脚本语言一般都是以文本形式存在，类似于一种命令。 <br>
举个例子说，如果你建立了一个程序，叫aaa.exe，可以打开.aa为扩展名的文件。你为.aa文件的编写指定了一套规则(语法)，当别人编写了.aa
文件后，你的程序用这种规则来理解编写人的意图，并作出回应.那么，这一套规则就是脚本语言。 <br>
<strong><font size="3">JAVA语言<br>
</font></strong>　java很特殊，java程序也需要编译，但是没有直接编译称为机器语言，而是编译称为字节码，然后用解释方式执行字
节码。Java既可以被编译，也可以被解释。通过编译器，可以把Java程序翻译成一种中间代码 - 称为字节码 -
可以被Java解释器解释的独立于平台的代码。通过解释器，每条Java字节指令被分析，然后在计算机上运行。只需编译一次，程序运行时解释执行。下图说
明了它是如何工作的：</span></font></p>
<font size="2"><span><span align="left"><img  src="http://hiphotos.baidu.com/our_poll/pic/item/c451a3a6ee06d8dcd1435891.jpg" class="blogimg" small="0" align="left" border="0"></span></span></font><font size="2"><span>
<p><br>
可以把Java字节码看作运行在Java虚拟机（Java
VM）上的机器代码指令。每种Java解释器，不管是Java开发工具还是可以运行Java小应用程序的Web浏览器，都是一种Java
VM的实例。JavaVM也可以由硬件实现。</p>
<p>　Java字节码使&#8220;写一次，到处运行&#8221;成为可能。可以在任何有Java编译器的平台上把Java程序编译成字节码。这个字节码可以运行在任何
Java VM上。例如，同一个Java程序可以运行在WindowsNT、Solaris和Macintosh上。</p>
<p align="center"><span align="right"><img  src="http://hiphotos.baidu.com/our_poll/pic/item/472175ef13232a602df53499.jpg" class="blogimg" small="0" align="right" border="0"></span>
</p>
<p>Java平台</p>
<p>　平台是程序运行的硬件或软件环境。Java平台与大多数其它平台不同之处在于它是运行于其它基于硬件平台的纯软件平台。大多数其它平台是硬件和操
作系统的结合。</p>
<p>Java平台由两部分组成：</p>
<p>&#8226;Java虚拟机（Java VM） <br>
&#8226;Java应用程序界面（Java API） <br>
Java VM是Java平台的基础，可以移植到各种基于硬件的平台上。Java
API是软件组件的集合，它们提供了很多有用的功能，如图形用户界面（GUI）。Java API被分组为相关组件的库（包）。</p>
<p>　下图描述了一个运行在Java平台上的Java程序，如应用程序（application）或小应用程序（applet）。如图中显示
的，JavaAPI和VM把Java程序从硬件依赖中分离出来。</p>
<p align="left"><span><img  src="http://hiphotos.baidu.com/our_poll/pic/item/786c0ac5fc0a53e08326ac74.jpg" class="blogimg" small="0" border="0"></span></p>
<p>作为一种独立于平台的环境，Java比本地代码慢一些。然而，聪明的编译器、很好地调制过的解释器和即时字节码编译器可以在不牺牲可移植性的条件下
使Java的表现接近本地代码。</p>
</span></font><img src ="http://www.cnitblog.com/stomic/aggbug/71156.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/stomic/" target="_blank">大话人生</a> 2010-11-10 16:50 <a href="http://www.cnitblog.com/stomic/archive/2010/11/10/71156.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Tomcat Catalina.bat解读</title><link>http://www.cnitblog.com/stomic/archive/2009/09/11/61359.html</link><dc:creator>大话人生</dc:creator><author>大话人生</author><pubDate>Thu, 10 Sep 2009 18:06:00 GMT</pubDate><guid>http://www.cnitblog.com/stomic/archive/2009/09/11/61359.html</guid><wfw:comment>http://www.cnitblog.com/stomic/comments/61359.html</wfw:comment><comments>http://www.cnitblog.com/stomic/archive/2009/09/11/61359.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/stomic/comments/commentRss/61359.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/stomic/services/trackbacks/61359.html</trackback:ping><description><![CDATA[<span class=hilite1><font style="BACKGROUND-COLOR: #ffff00">Catalina</font></span>.<span class=hilite2><font style="BACKGROUND-COLOR: #55ff55">bat</font></span>是tomcat所有脚本中最重要的脚本，完成几乎所有的tomcat操作。如启动，关闭等等,都是由<span class=hilite1><font style="BACKGROUND-COLOR: #ffff00">catalina</font></span>.<span class=hilite2><font style="BACKGROUND-COLOR: #55ff55">bat</font></span>脚本来完成的。接下来，我将对Tomcat <span class=hilite1><font style="BACKGROUND-COLOR: #ffff00">catalina</font></span>.<span class=hilite2><font style="BACKGROUND-COLOR: #55ff55">bat</font></span>脚本进行分析。 <br><br>&nbsp;&nbsp;&nbsp; 首先省去<span class=hilite1><font style="BACKGROUND-COLOR: #ffff00">catalina</font></span>.<span class=hilite2><font style="BACKGROUND-COLOR: #55ff55">bat</font></span>开头诸多注解，这些注解主要是讲解各个变量是干什么的。需要的话，自己看下英文就可以了。这里就不翻译了。 <br><br>rem Guess CATALINA_HOME if not defined&nbsp; 查看是否在tomcat目录下，与startup.<span class=hilite2><font style="BACKGROUND-COLOR: #55ff55">bat</font></span>里相同，不解释了。需要的话可以看我的另一篇博客。 <br>set CURRENT_DIR=%cd% <br>if not "%CATALINA_HOME%" == "" goto gotHome <br>set CATALINA_HOME=%CURRENT_DIR% <br>if exist "%CATALINA_HOME%\bin\<span class=hilite1><font style="BACKGROUND-COLOR: #ffff00">catalina</font></span>.<span class=hilite2><font style="BACKGROUND-COLOR: #55ff55">bat</font></span>" goto okHome <br>cd .. <br>set CATALINA_HOME=%cd% <br>cd %CURRENT_DIR% <br>:gotHome <br>if exist "%CATALINA_HOME%\bin\<span class=hilite1><font style="BACKGROUND-COLOR: #ffff00">catalina</font></span>.<span class=hilite2><font style="BACKGROUND-COLOR: #55ff55">bat</font></span>" goto okHome <br>echo The CATALINA_HOME environment variable is not defined correctly <br>echo This environment variable is needed to run this program <br>goto end <br>:okHome <br><br>rem Get standard environment variables <br>if exist "%CATALINA_HOME%\bin\setenv.<span class=hilite2><font style="BACKGROUND-COLOR: #55ff55">bat</font></span>" call "%CATALINA_HOME%\bin\setenv.<span class=hilite2><font style="BACKGROUND-COLOR: #55ff55">bat</font></span>" 如果存在setenv.<span class=hilite2><font style="BACKGROUND-COLOR: #55ff55">bat</font></span>脚本，调用它，我的tomcat 没有这个脚本 <br><br>rem Get standard Java environment variables <br>if exist "%CATALINA_HOME%\bin\setclasspath.<span class=hilite2><font style="BACKGROUND-COLOR: #55ff55">bat</font></span>" goto okSetclasspath 查看是否存在setclasspath.<span class=hilite2><font style="BACKGROUND-COLOR: #55ff55">bat</font></span>脚本，如果存在，转到okSetclasspath位置 <br>echo Cannot find %CATALINA_HOME%\bin\setclasspath.<span class=hilite2><font style="BACKGROUND-COLOR: #55ff55">bat</font></span> 否则输出下面两行，并退出 <br>echo This file is needed to run this program <br>goto end <br>:okSetclasspath&nbsp;&nbsp;&nbsp; okSetclasspath位置 <br><br>set BASEDIR=%CATALINA_HOME%&nbsp;&nbsp; 设定BASEDIR变量与CATALINA_HOME变量值相同 <br>call "%CATALINA_HOME%\bin\setclasspath.<span class=hilite2><font style="BACKGROUND-COLOR: #55ff55">bat</font></span>" %1&nbsp;&nbsp; 调用setclasspath.<span class=hilite2><font style="BACKGROUND-COLOR: #55ff55">bat</font></span>脚本并加上参数 <br>if errorlevel 1 goto end&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果存在错误 退出 <br><br>rem Add on extra jar files to CLASSPATH&nbsp;&nbsp; 设定JSSE_HOME变量，如果存在加入CLASSPATH，不存在跳过 <br><br>if "%JSSE_HOME%" == "" goto noJsse&nbsp;&nbsp;&nbsp; 检查是否存在JSSE_HOME变量 <br>set CLASSPATH=%CLASSPATH%;%JSSE_HOME%\lib\jcert.jar;%JSSE_HOME%\lib\jnet.jar;%JSSE_HOME%\lib\jsse.jar 如果有加入到CLASSPATH变量后面 <br>:noJsse&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>set CLASSPATH=%CLASSPATH%;%CATALINA_HOME%\bin\bootstrap.jar&nbsp; 将bootstrap.jar加入到CLASSPATH里 <br><br>if not "%CATALINA_BASE%" == "" goto gotBase&nbsp; 如果CATALINA_BASE变量不为空，跳过，转到gotBase位置 <br>set CATALINA_BASE=%CATALINA_HOME%&nbsp; 如果为空，将CATALINA_BASE设为CATALINA_HOME变量的值 <br>:gotBase <br><br>if not "%CATALINA_TMPDIR%" == "" goto gotTmpdir&nbsp;&nbsp; CATALINA_TMPDIR不为空，跳过，转到gotTmpdir位置 <br>set CATALINA_TMPDIR=%CATALINA_BASE%\temp&nbsp;&nbsp; 如果为空，将 CATALINA_TMPDIR设为%CATALINA_BASE%\temp变量的值（即tomcat\temp） <br>:gotTmpdir <br><br>if not exist "%CATALINA_HOME%\bin\tomcat-juli.jar" goto noJuli&nbsp; 如果不存在tomcat-juli.jar这个类，转到noJuli位置 <br>set JAVA_OPTS=%JAVA_OPTS% -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager - Djava.util.logging.config.file="%CATALINA_BASE%\conf\logging.properties"&nbsp; 如果存在，将变量加入到JAVA_OPTS里 <br>:noJuli <br><br><br><span style="COLOR: red">set JAVA_OPTS=%JAVA_OPTS% -Xms128m -Xmx512m -Dfile</span>.encoding=UTF8 -Duser.timezone=GMT -Djava.security.auth.login.config=%CATALINA_HOME%/conf/jaas.config&nbsp; 设定JAVA_OPTS变量 <br><br>echo Using CATALINA_BASE:&nbsp;&nbsp; %CATALINA_BASE%&nbsp;&nbsp;&nbsp;&nbsp; 输出CATALINA_BASE变量值 <br>echo Using CATALINA_HOME:&nbsp;&nbsp; %CATALINA_HOME%&nbsp;&nbsp;&nbsp;&nbsp; 输出CATALINA_HOME变量值 <br>echo Using CATALINA_TMPDIR: %CATALINA_TMPDIR% 输出CATALINA_TMPDIR变量值 <br>if ""%1"" == ""debug"" goto use_jdk&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果变量%1里存在debug ，转到use_jdk位置 <br>echo Using JRE_HOME:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %JRE_HOME%&nbsp;&nbsp;&nbsp;&nbsp; 输出JRE_HOME变量值 <br>goto java_dir_displayed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 转到java_dir_displayed <br>:use_jdk <br>echo Using JAVA_HOME:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %JAVA_HOME%&nbsp;&nbsp;&nbsp; 输出JAVA_HOME变量值 <br>:java_dir_displayed <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 下面几行设定相应变量 <br>set _EXECJAVA=%_RUNJAVA%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>set MAINCLASS=org.apache.<span class=hilite1><font style="BACKGROUND-COLOR: #ffff00">catalina</font></span>.startup.Bootstrap <br>set ACTION=start <br>set SECURITY_POLICY_FILE= <br>set DEBUG_OPTS= <br>set JPDA= <br><br>if not ""%1"" == ""jpda"" goto noJpda <br>set JPDA=jpda <br>if not "%JPDA_TRANSPORT%" == "" goto gotJpdaTransport <br>set JPDA_TRANSPORT=dt_shmem <br>:gotJpdaTransport <br>if not "%JPDA_ADDRESS%" == "" goto gotJpdaAddress <br>set JPDA_ADDRESS=jdbconn <br>:gotJpdaAddress <br>if not "%JPDA_SUSPEND%" == "" goto gotJpdaSuspend <br>set JPDA_SUSPEND=n <br>:gotJpdaSuspend <br>if not "%JPDA_OPTS%" == "" goto gotJpdaOpts <br>set JPDA_OPTS=-Xdebug -Xrunjdwp:transport=%JPDA_TRANSPORT%,address=%JPDA_ADDRESS%,server=y,suspend=%JPDA_SUSPEND% <br>:gotJpdaOpts <br>shift <br>:noJpda <br><br>if ""%1"" == ""debug"" goto doDebug&nbsp;&nbsp;&nbsp; 如果%1为debug，转到doDebug，运行debug模式 <br>if ""%1"" == ""run"" goto doRun&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果%1为run，转到doRun，运行正常模式 <br>if ""%1"" == ""start"" goto doStart&nbsp;&nbsp;&nbsp; 如果%1为start，转到doStart，启动tomcat <br>if ""%1"" == ""stop"" goto doStop&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果%1为stop，转到doStop，关闭tocmat <br>if ""%1"" == ""version"" goto doVersion 如果%1为version，转到doVersion，显示tomcat的版本号 <br><br>echo Usage:&nbsp; <span class=hilite1><font style="BACKGROUND-COLOR: #ffff00">catalina</font></span> ( commands ... ) 如果%1没有上述内容，输出下面几行，并结束 <br>echo commands: <br>echo&nbsp;&nbsp; debug&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Start <span class=hilite1><font style="BACKGROUND-COLOR: #ffff00">Catalina</font></span> in a debugger <br>echo&nbsp;&nbsp; debug -security&nbsp;&nbsp; Debug <span class=hilite1><font style="BACKGROUND-COLOR: #ffff00">Catalina</font></span> with a security manager <br>echo&nbsp;&nbsp; jpda start&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Start <span class=hilite1><font style="BACKGROUND-COLOR: #ffff00">Catalina</font></span> under JPDA debugger <br>echo&nbsp;&nbsp; run&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Start <span class=hilite1><font style="BACKGROUND-COLOR: #ffff00">Catalina</font></span> in the current window <br><br>echo&nbsp;&nbsp; run -security&nbsp;&nbsp;&nbsp;&nbsp; Start in the current window with security manager <br>echo&nbsp;&nbsp; start&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Start <span class=hilite1><font style="BACKGROUND-COLOR: #ffff00">Catalina</font></span> in a separate window <br>echo&nbsp;&nbsp; start -security&nbsp;&nbsp; Start in a separate window with security manager <br>echo&nbsp;&nbsp; stop&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Stop <span class=hilite1><font style="BACKGROUND-COLOR: #ffff00">Catalina</font></span> <br>echo&nbsp;&nbsp; version&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; What version of tomcat are you running? <br>goto end <br><br>:doDebug <br>shift&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 将%2里的值转到%1 <br>set _EXECJAVA=%_RUNJDB%&nbsp; 将变量 _EXECJAVA设为_RUNJDB变量的值 <br>set DEBUG_OPTS=-sourcepath "%CATALINA_HOME%\..\..\jakarta-tomcat-<span class=hilite1><font style="BACKGROUND-COLOR: #ffff00">catalina</font></span>\<span class=hilite1><font style="BACKGROUND-COLOR: #ffff00">catalina</font></span>\src\share"&nbsp; <br>设定DEBUG_OPTS变量 <br><br>if not ""%1"" == ""-security"" goto execCmd&nbsp;&nbsp;&nbsp; <br>如果%1不为-security，转到execCmd位置 <br><br>shift&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 将%2里的值转到%1 <br>echo Using Security Manager&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 输出该行 <br>set SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\<span class=hilite1><font style="BACKGROUND-COLOR: #ffff00">catalina</font></span>.policy <br>设定SECURITY_POLICY_FILE变量的值 <br><br>goto execCmd&nbsp;&nbsp;&nbsp;&nbsp; 转到execCmd位置 <br><br>:doRun <br>shift&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 将%2里的值转到%1 <br>if not ""%1"" == ""-security"" goto execCmd&nbsp;&nbsp; 如果%1不为-security，转到execCmd位置 <br>shift&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 将%2里的值转到%1 <br>echo Using Security Manager&nbsp;&nbsp; 输出该行 <br>set SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\<span class=hilite1><font style="BACKGROUND-COLOR: #ffff00">catalina</font></span>.policy <br>设定SECURITY_POLICY_FILE变量的值 <br><br>goto execCmd&nbsp; 转到execCmd位置 <br><br>:doStart <br>shift&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 将%2里的值转到%1 <br>if not "%OS%" == "Windows_NT" goto noTitle&nbsp; 如果OS变量不为Windows_NT，转到noTitle <br>set _EXECJAVA=start "Tomcat" %_RUNJAVA%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 设定_EXECJAVA变量的值 <br>goto gotTitle&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 转到gotTitle位置 <br>:noTitle <br>set _EXECJAVA=start %_RUNJAVA%&nbsp;&nbsp;&nbsp; 设定 _EXECJAVA 变量的值 <br>:gotTitle&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>if not ""%1"" == ""-security"" goto execCmd&nbsp;&nbsp; 如果%1不为-security，转到execCmd位置 <br>shift&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 将%2里的值转到%1 <br>echo Using Security Manager&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 输出该行 <br>set SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\<span class=hilite1><font style="BACKGROUND-COLOR: #ffff00">catalina</font></span>.policy&nbsp;&nbsp; <br>设定SECURITY_POLICY_FILE变量的值 <br><br>goto execCmd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 转到execCmd位置 <br><br>:doStop <br>shift&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 将%2里的值转到%1 <br>set ACTION=stop&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 将ACTION的变量设为stop <br>set CATALINA_OPTS=&nbsp;&nbsp;&nbsp; 设CATALINA_OPTS为空 <br><br>goto execCmd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 转到execCmd位置 <br><br>:doVersion&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 显示tomcat版本号 <br>%_EXECJAVA% -classpath "%CATALINA_HOME%\server\lib\<span class=hilite1><font style="BACKGROUND-COLOR: #ffff00">catalina</font></span>.jar" org.apache.<span class=hilite1><font style="BACKGROUND-COLOR: #ffff00">catalina</font></span>.util.ServerInfo&nbsp;&nbsp; 执行该命令 <br>goto end&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 结束该程序 <br><br>:execCmd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>rem Get remaining unshifted command line arguments and save them in the <br>以下几行将命令参数存入CMD_LINE_ARGS变量中 <br><br>set CMD_LINE_ARGS= <br>:setArgs <br>if ""%1""=="""" goto doneSetArgs <br>set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1 <br>shift <br>goto setArgs <br>:doneSetArgs <br><br>rem Execute Java with the applicable properties <br>if not "%JPDA%" == "" goto doJpda&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果JPDA变量不为空，转到doJpda位置 <br>if not "%SECURITY_POLICY_FILE%" == "" goto doSecurity <br>如果SECURITY_POLICY_FILE变量不为空，转到doSecurity位置 <br><br>如果都没有执行下面命令，并结束该程序 <br>%_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION% <br>goto end <br>:doSecurity&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 执行下面命令，并结束该程序 <br>%_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Djava.security.manager -Djava.security.policy=="%SECURITY_POLICY_FILE%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION% <br>goto end <br>:doJpda&nbsp;&nbsp; <br>如果SECURITY_POLICY_FILE变量不为空，转到doSecurityJpda位置，为空执行下面命令，并结束该程序&nbsp;&nbsp; <br><br>if not "%SECURITY_POLICY_FILE%" == "" goto doSecurityJpda <br>%_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %JPDA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION% <br>goto end <br>:doSecurityJpda&nbsp; 执行下面命令，并结束该程序 <br>%_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %JPDA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Djava.security.manager -Djava.security.policy=="%SECURITY_POLICY_FILE%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION% <br>goto end <br><br>:end <br><br>终结： <br><br>&nbsp;&nbsp; <span class=hilite1><font style="BACKGROUND-COLOR: #ffff00">catalina</font></span>.<span class=hilite2><font style="BACKGROUND-COLOR: #55ff55">bat</font></span>咋一看还以为是什么windows程序，可以双击运行，实际上就是调用java命令运行Bootstrap类。从上面代码可以看出tomcat确实是一个纯java的程序，脚本最后都变成直接使用java命令执行程序，与我们普通写的java程序，没有什么不同。只不过由于 tomcat可以使用各种众多的模式（如debug,Security等），以及各种需要各种参数所以不得不使用脚本来执行。 <br><br>如果你想看看你到底使用了什么命令可以在&#8220;if not "%SECURITY_POLICY_FILE%" == "" goto doSecurity&#8221;这行下面添加两行。 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo&nbsp; %_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dir ....（下面那段，是一行但太长，折行了） <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pause <br>&nbsp;&nbsp; 第一行的命令是打印这具话，系统会将% %里面的变量提换成找到的值并输出。第二行是暂停程序，你可以通过任意键来恢复运行。 <br>&nbsp;&nbsp; 下面是我的程序打印的结果： <br><br>start "Tomcat" "C:\Program Files\Java\jdk1.6.0_01\bin\java"&nbsp; -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.util.logging.config.file="C:\work\tomcat\conf\logging.properties" -Xms128m -Xmx512m -Dfile.encoding=UTF8 -Duser.timezone=GMT -Djava.security.auth.login.config=C:\work\tomcat/conf/jaas.config&nbsp;&nbsp; -Djava.endorsed.dirs="C:\work\tomcat\common\endorsed" -classpath "C:\Program Files\Java\jdk1.6.0_01\lib\tools.jar;C:\work\tomcat\bin\bootstrap.jar" -Dcatalina.base="C:\work\tomcat" -Dcatalina.home="C:\work\tomcat" -Djava.io.tmpdir="C:\work\tomcat\temp" org.apache.<span class=hilite1><font style="BACKGROUND-COLOR: #ffff00">catalina</font></span>.startup.Bootstrap&nbsp; start <br><br>&nbsp;&nbsp;&nbsp; start "tomcat"是另开一个窗口，窗口名是tomcat的意思，你可以去掉这部分，完将你程序打印的拷贝到命令行下，点回车，看是不是一样运行 tomcat了。<span class=hilite1><font style="BACKGROUND-COLOR: #ffff00">Catalina</font></span>.<span class=hilite2><font style="BACKGROUND-COLOR: #55ff55">bat</font></span> startup实际时就将各种系统变量加以总结，输出成这个命令。&nbsp;&nbsp; 呵呵! 
<img src ="http://www.cnitblog.com/stomic/aggbug/61359.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/stomic/" target="_blank">大话人生</a> 2009-09-11 02:06 <a href="http://www.cnitblog.com/stomic/archive/2009/09/11/61359.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Tomcat startup.bat解读</title><link>http://www.cnitblog.com/stomic/archive/2009/09/11/61358.html</link><dc:creator>大话人生</dc:creator><author>大话人生</author><pubDate>Thu, 10 Sep 2009 17:53:00 GMT</pubDate><guid>http://www.cnitblog.com/stomic/archive/2009/09/11/61358.html</guid><wfw:comment>http://www.cnitblog.com/stomic/comments/61358.html</wfw:comment><comments>http://www.cnitblog.com/stomic/archive/2009/09/11/61358.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/stomic/comments/commentRss/61358.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/stomic/services/trackbacks/61358.html</trackback:ping><description><![CDATA[<div class=blog_content>
<p>@echo off&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: red">//DOS在运行批处理时，会依次执行批处理中的每条命令，并且会在显示器上显示，如果你不想让它们显示，可以加一个&#8220;echo off&#8221;。当然，&#8220;echo off&#8221;也是命令，它本身也会显示，如果连这条也不显示，就在前面加个&#8220;@&#8221;。</span> </p>
<p>if "%OS%" == "Windows_NT" <a href="http://www.tomly.cn/bbs/ShowPost.asp?ThreadID=102"><u><font color=#000000>setlocal</font></u></a> &nbsp;&nbsp; <span style="COLOR: #ff0000">//判断当前系统是否是window系统</span> <br>rem ---------------------------------------------------------------------------&nbsp; <span style="COLOR: #ff0000">//rem 是注释（下同）</span> <br>rem Start script for the CATALINA Server<br>rem<br>rem $Id: <span class=hilite1><font style="BACKGROUND-COLOR: #ffff00">startup</font></span>.<span class=hilite2><font style="BACKGROUND-COLOR: #55ff55">bat</font></span> 302918 2004-05-27 18:25:11Z yoavs $<br>rem ---------------------------------------------------------------------------<br><br>rem Guess CATALINA_HOME if not defined<br>set CURRENT_DIR=%cd%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #ff0000">//设置当前目录</span> <br>if not "%CATALINA_HOME%" == "" goto gotHome <span style="COLOR: #ff0000">//如果设置了CATALINA_HOME<span style="FONT-SIZE: x-small"><font size=1><strong>环境变量</strong> </font></span>，就直接到下面的gotHome处</span> <br>set CATALINA_HOME=%CURRENT_DIR% <span style="COLOR: #ff0000">//如果没有设置CATALINA_HOME，就设置CATALINA_HOME为当前目录（其实这里她假设你进入<span class=hilite3><font style="BACKGROUND-COLOR: #aaffaa">tomcat</font></span>的安装目录）</span> <br>if exist "%CATALINA_HOME%\bin\catalina.<span class=hilite2><font style="BACKGROUND-COLOR: #55ff55">bat</font></span>" goto okHome<span style="COLOR: #ff0000">//判断一下catalina.<span class=hilite2><font style="BACKGROUND-COLOR: #55ff55">bat</font></span>是否找到了，找到了就直接到下面的gotHome处</span> <br>cd .. <span style="COLOR: #ff0000">//这里他是假设你开始已经进入到了<span class=hilite3><font style="BACKGROUND-COLOR: #aaffaa">tomcat</font></span>的bin目录，所以就退到上一级目录</span> <br>set CATALINA_HOME=%cd%<span style="COLOR: #ff0000">//现在再设置CATALINA_HOME为<span class=hilite3><font style="BACKGROUND-COLOR: #aaffaa">tomcat</font></span>的安装目录</span> <br>cd %CURRENT_DIR% <span style="COLOR: #ff0000">//这里是进入dos的当前目录</span> <br><span style="COLOR: #0000ff">:gotHome</span> <br>if exist "%CATALINA_HOME%\bin\catalina.<span class=hilite2><font style="BACKGROUND-COLOR: #55ff55">bat</font></span>" goto okHome&nbsp; <span style="COLOR: #ff0000">//再次判断catalina.<span class=hilite2><font style="BACKGROUND-COLOR: #55ff55">bat</font></span>是否找到了，找到了就直接到下面的okHome处，没有的话，就只能提示你啦！</span> <br>echo The CATALINA_HOME environment variable is not defined correctly<br>echo This environment variable is needed to run this program<br>goto end<br><span style="COLOR: #0000ff">:okHome</span> <br><br>set EXECUTABLE=%CATALINA_HOME%\bin\catalina.<span class=hilite2><font style="BACKGROUND-COLOR: #55ff55">bat</font></span>&nbsp; <span style="COLOR: #ff0000">//设置要执行的文件</span> <br><br>rem Check that target executable exists<br>if exist "%EXECUTABLE%" goto okExec <span style="COLOR: #ff0000">//再次判断catalina.<span class=hilite2><font style="BACKGROUND-COLOR: #55ff55">bat</font></span>是否找到了，找到了就直接到下面的okExec处，没有的话，就提示。</span> <br>echo Cannot find %EXECUTABLE%<br>echo This file is needed to run this program<br>goto end<br><span style="COLOR: #0000ff">:okExec</span> <br><br>rem Get remaining unshifted command line arguments and save them in the<br>set CMD_LINE_ARGS= <span style="COLOR: #ff0000">//这里是设置参数</span> <br><span style="COLOR: #0000ff">:setArgs</span> <br>if ""%1""=="""" goto doneSetArgs <span style="COLOR: #ff0000">//判断参数是否加入完成</span> <br>set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1 <span style="COLOR: #ff0000">//将参数组成一行，接在后面</span> <br>shift<br>goto setArgs<br><span style="COLOR: #0000ff">:doneSetArgs</span> </p>
<p>call "%EXECUTABLE%" start %CMD_LINE_ARGS% <span style="COLOR: #ff0000">//执行catalina.<span class=hilite2><font style="BACKGROUND-COLOR: #55ff55">bat</font></span>，最好将这行改为:<em><strong>echo "%EXECUTABLE%" start %CMD_LINE_ARGS%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong></em>以便阅读、理解本文件的作用</span> <br><br><span style="COLOR: #0000ff">:end</span> </p>
<p>&nbsp;</p>
<p>//这个批处理文件，主要是正确的找到catalina.<span class=hilite2><font style="BACKGROUND-COLOR: #55ff55">bat</font></span>，并且执行。</p>
<ul>
    <li>当把<span class=hilite3><font style="BACKGROUND-COLOR: #aaffaa">tomcat</font></span>解压到一个地方时，通常是设置一个<span style="COLOR: #ff0000"><span style="COLOR: #000000">CATALINA_HOME的环境变量，执行这个文件时，就很容易找到</span> </span>catalina.<span class=hilite2><font style="BACKGROUND-COLOR: #55ff55">bat</font></span>
    <li>如果没有设置<span style="COLOR: #ff0000"><span style="COLOR: #000000">CATALINA_HOME的环境变量，那么你需要在dos中进入<span class=hilite3><font style="BACKGROUND-COLOR: #aaffaa">tomcat</font></span>的安装目录，或者bin...子目录，再执行这个文件，如果在其他目录，将会出现提示找不到文件。</span> </span>【针对<span class=hilite1><font style="BACKGROUND-COLOR: #ffff00">startup</font></span>.<span class=hilite2><font style="BACKGROUND-COLOR: #55ff55">bat</font></span>文件】
    <li>双击该文件时，%cd%的值为当前目录的值，所有执行是没有问题的。 </li>
</ul>
</div>
<img src ="http://www.cnitblog.com/stomic/aggbug/61358.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/stomic/" target="_blank">大话人生</a> 2009-09-11 01:53 <a href="http://www.cnitblog.com/stomic/archive/2009/09/11/61358.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java初始化顺序</title><link>http://www.cnitblog.com/stomic/archive/2009/08/28/61062.html</link><dc:creator>大话人生</dc:creator><author>大话人生</author><pubDate>Fri, 28 Aug 2009 09:54:00 GMT</pubDate><guid>http://www.cnitblog.com/stomic/archive/2009/08/28/61062.html</guid><wfw:comment>http://www.cnitblog.com/stomic/comments/61062.html</wfw:comment><comments>http://www.cnitblog.com/stomic/archive/2009/08/28/61062.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/stomic/comments/commentRss/61062.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/stomic/services/trackbacks/61062.html</trackback:ping><description><![CDATA[<p>初始化（initialization）其实包含两部分：<br>1.类的初始化（initialization class &amp; interface）<br>2.对象的创建（creation of new class instances）。<br>因为类的初始化其实是类加载（loading of classes）的最后一步，所以很多书中把它归结为&#8220;对象的创建&#8221;的第一步。其实只是看问题的角度不同而已。为了更清楚的理解，这里还是分开来。</p>
<p>顺序：<br>应为类的加载肯定是第一步的，所以类的初始化在前。大体的初始化顺序是：<br>类初始化 -&gt; 子类构造函数 -&gt; 父类构造函数 -&gt; 实例化成员变量 -&gt; 继续执行子类构造函数的语句</p>
<p>下面结合例子，具体解释一下。<br>1。类的初始化（Initialization classes and interfaces），其实很简单，具体来说有：<br>（a）初始化类（initialization of class），是指初始化static field 和执行static初始化块。<br>例如：<br>class Super {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static String s = &#8220;initialization static field&#8221;; //初始化static field，其中&#8220;= &#8220;initialization static field&#8221; &#8221;又叫做static field initializer</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // static初始化块，又叫做static initializer，或 static initialization block<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(&#8220;This is static initializer&#8221;);<br>}<br>}<br>btw，有些书上提到static initializer 和 static field initializer 的概念，与之对应的还有 instance initializer 和 instance variable initializer。例子中的注释已经解释了其含义。</p>
<p>（b）初始化接口（initialization of interface），是指初始化定义在该interface中的field。</p>
<p>*注意*<br>--initialization classes 时，该class的superclass 将首先被初始化，但其实现的interface则不会。<br>--initialization classes 时，该class的superclass，以及superlcass的superclass 会首先被递归地初始化，一直到java.lang.Object为止。但initialiazation interface的时候，却不需如此，只会初始化该interface本身。<br>--对于由引用类变量（class field）所引发的初始化，只会初始化真正定义该field的class。<br>--如果一个static field是编译时常量（compile-time constant），则对它的引用不会引起定义它的类的初始化。</p>
<p>为了帮助理解最后两点，请试试看下面的例子：<br>public class Initialization {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static void main(String[] args) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(Sub.x); // Won't cause initialization of Sub, because x is declared by S, not Sub.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 不会引起Sub类的初始化，因为x是定义在Super类中的<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("-------------------------");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(Sub.y); // Won't cause initialization of Sub, because y is constant.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 不会引起Sub类的初始化，因为y是常量<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("-------------------------");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(Sub.z = 2004); // Will cause initialization of Sub class<br>// 将会引起Sub的初始化<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>}</p>
<p>class Super{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static int x = 2006;<br>}</p>
<p>class Sub extends Super {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static final int y = 2005;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>static int z;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>static {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Initialization Sub");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>}</p>
<p>2。对象的创建（creation of new class instances），稍微有点烦琐，具体的步骤如下<br>(a) 所有的成员变量—包括该类，及它的父类中的成员变量--被分配内存空间，并赋予默认值。（Btw，这里是第一次初始化成员变量）<br>(b) 为所调用的构造函数初始化其参数变量。（如果有参数）<br>(c) 如果在构造函数中用this 调用了同类中的其他构造函数，则按照步骤(b)~(f)去处理被调用到的构造函数。<br>(d) 如果在构造函数中用super调用了其父类的构造函数，则按照步骤(b)~(f)去处理被调用到的父类构造函数。<br>(e) 按照书写顺序，执行instance initializer 和 instance variable initializer来初始化成员变量。（Btw，这里是第二次初始化成员变量）<br>(f) 按照书写顺序，执行constructor的其余部分。</p>
<p>*注意*<br>成员变量其实都被初始化2次，第一次是赋予默认值，第二次才是你想要设定的值。</p>
<p>最后看一个例子：<br>public class InitializationOrder {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static void main(String[] args) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Subclass sb = new Subclass();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>}</p>
<p>class Super{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(1);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Super(int i){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(i);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>}</p>
<p>class Subclass extends Super implements Interface{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(2);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Super su = new Super(4);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Subclass() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super(3);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new Super(5);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>}</p>
<p>interface Interface{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static Super su = new Super(0);<br>}</p>
<p>稍微解释一下：<br>首先，Java虚拟机要执行InitializationOrder类中的static 方法main()，这引起了类的初始化。开始初始化InitializationOrder类。具体的步骤略去不说。<br>接着，InitializationOrder类初始化完毕后，开始执行main()方法。语句Subclass sb = new Subclass()将创建一个Subclass对象。加载类Subclass后对其进行类初始化，但因为Subclass有一个父类Super，所以先初始化Super类，初始化块static {System.out.println(1);}被执行，打印输出1；<br>第三，Super初始化完毕后，开始初始化Subclass类。static {System.out.println(2);}被执行，打印输出2；<br>第四，至此，类的加载工作全部完成。开始进入创建Subclass的对象过程。先为Subclass类和其父类Super类分配内存空间，这时Super su 被附值为null;<br>第五，执行构造函数Subclass()时，super(3)被执行。如前面(d)所说，Super类的构造函数Super(int i){&#8230;.}被调用，并按照步骤(b)~(f)来处理。因此，递归调用Super类的父类Object类的构造函数，并按照步骤(b)~(f)来初始化Object类，不过没有任何输入结果。最后打印输出3；<br>第六，如前面(e)所说，初始化成员变量su，其结果是打印输出4；<br>第七，如前面(f)所说，执行new Super(5)，并打印输出5；<br>最后，Subclass虽然实现了接口Interface，但是初始化它的时候并不会引起接口的初始化，所以接口Interface中的static Super su = new Super(0)自始至终都没有被执行到。</p>
<p><br>① 类属性 (静态变量) 定义时的初始化，如上例的 static String a = "string-a";<br>&nbsp;&nbsp;&nbsp; ② static 块中的初始化代码，如上例 static {} 中的 b = "string-b";<br>&nbsp;&nbsp;&nbsp; ③ 对象属性 (非静态变量) 定义时的初始化，如上例的 String c = "stirng-c";<br>&nbsp;&nbsp;&nbsp; ④ 构造方法 (函数) 中的初始化代码，如上例构造方法中的 d = "string-d";</p>
<p>&nbsp;</p>
<p>本文来自CSDN博客，转载请标明出处：<a href="http://blog.csdn.net/socoolfj/archive/2006/05/23/750425.aspx">http://blog.csdn.net/socoolfj/archive/2006/05/23/750425.aspx</a></p>
<img src ="http://www.cnitblog.com/stomic/aggbug/61062.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/stomic/" target="_blank">大话人生</a> 2009-08-28 17:54 <a href="http://www.cnitblog.com/stomic/archive/2009/08/28/61062.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java 文件名与类名的一致性</title><link>http://www.cnitblog.com/stomic/archive/2009/08/27/61034.html</link><dc:creator>大话人生</dc:creator><author>大话人生</author><pubDate>Thu, 27 Aug 2009 06:05:00 GMT</pubDate><guid>http://www.cnitblog.com/stomic/archive/2009/08/27/61034.html</guid><wfw:comment>http://www.cnitblog.com/stomic/comments/61034.html</wfw:comment><comments>http://www.cnitblog.com/stomic/archive/2009/08/27/61034.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/stomic/comments/commentRss/61034.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/stomic/services/trackbacks/61034.html</trackback:ping><description><![CDATA[<table style="TABLE-LAYOUT: fixed; WIDTH: 100%">
    <tbody>
        <tr>
            <td>
            <div class=cnt id=blog_text>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1"><font face="Times New Roman"><span><span style="mso-list: Ignore">1.<span style="FONT: 7pt Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span>Java</span></font><span>保存的文件名必须与类名一致；</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1"><span><span style="mso-list: Ignore"><font face="Times New Roman">2.<span style="FONT: 7pt Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></font></span></span><span>如果文件中只有一个类，文件名必须与类名一致；</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1"><span><span style="mso-list: Ignore"><font face="Times New Roman">3.<span style="FONT: 7pt Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></font></span></span><span>一个</span><span><font face="Times New Roman">Java</font></span><span>文件中只能有一个</span><span><font face="Times New Roman">public</font></span><span>类；</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1"><span><span style="mso-list: Ignore"><font face="Times New Roman">4.<span style="FONT: 7pt Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></font></span></span><span>如果文件中不止一个类，文件名必须与</span><span><font face="Times New Roman">public</font></span><span>类名一致；</span></p>
            <p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1"><span><span style="mso-list: Ignore"><font face="Times New Roman">5.<span style="FONT: 7pt Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></font></span></span><span>如果文件中不止一个类，而且没有</span><span><font face="Times New Roman">public</font></span><span>类，文件名可与任一类名一致；</span></p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.cnitblog.com/stomic/aggbug/61034.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/stomic/" target="_blank">大话人生</a> 2009-08-27 14:05 <a href="http://www.cnitblog.com/stomic/archive/2009/08/27/61034.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>（转）hibernate 入门 :10 分钟跑起这个 hibernate 示例程序 ( 图解、附源码 ) </title><link>http://www.cnitblog.com/stomic/archive/2009/07/07/59916.html</link><dc:creator>大话人生</dc:creator><author>大话人生</author><pubDate>Tue, 07 Jul 2009 08:37:00 GMT</pubDate><guid>http://www.cnitblog.com/stomic/archive/2009/07/07/59916.html</guid><wfw:comment>http://www.cnitblog.com/stomic/comments/59916.html</wfw:comment><comments>http://www.cnitblog.com/stomic/archive/2009/07/07/59916.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/stomic/comments/commentRss/59916.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/stomic/services/trackbacks/59916.html</trackback:ping><description><![CDATA[<h3 class=type_original title=原创><a href="http://wangyi878750.javaeye.com/blog/246871"><u><font color=#108ac6>hibernate 入门:10分钟跑起这个hibernate 示例程序 (图解、附源码) </font></u></a></h3>
<div class=blog_content>
<p align=center><font size=2><strong><span style="FONT-SIZE: small"><span>hibernate </span></span></strong><span><strong><span style="FONT-SIZE: small"><span>入门</span> </span></strong></span><strong><span style="FONT-SIZE: small"><span>:10</span> </span></strong><span><strong><span style="FONT-SIZE: small"><span>分钟跑起这个</span> </span></strong></span><strong><span style="FONT-SIZE: small"><span>hibernate </span></span></strong><span><strong><span style="FONT-SIZE: small"><span>示例程序 </span></span></strong></span><strong><span style="FONT-SIZE: small"><span>(</span> </span></strong><span><strong><span style="FONT-SIZE: small"><span>图解、附源码</span> </span></strong></span><strong><span style="FONT-SIZE: small"><span>)</span> </span></strong></font></p>
<p>&nbsp;</p>
<p><span>关于</span> Hibernate,<span>我就不多说什么了</span> ,<span>这里是一个单纯的</span> Hibernate<span>的</span> Demo,<span>让你按照这里所写的代码</span> ,<span>让你在</span> 10<span>分钟之内把它跑起来</span> .<span>让初学者能够看到</span> hibernate<span>的美妙</span> .</p>
<p>&nbsp;</p>
<p><span>本</span> Demo<span>开发环境</span> :</p>
<p>?? WindowsXP</p>
<p>?? jdk . 1.5.0_12</p>
<p>?? MySQL 4.1</p>
<p>?? Eclipse 3.2.2</p>
<p>?? hibernate-3.3.1.GA</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span>前提</span> :<span>已经安装有</span> JDK<span>和</span> Eclipse.(<span>带</span> Lomboz),<span>以及</span> MySQL,<span>如果相关软件和</span> jar<span>包没有的话</span> ,<span>请自行</span> google.</p>
<p>&nbsp;</p>
<p><span>下载</span> hibernate-3.3.1.GA</p>
<p>&nbsp;</p>
<p><span>打开</span> Eclipse,<span>新建一个</span> Java<span>项目</span> </p>
<p><img height=588 alt="" src="http://docs.google.com/File?id=dd74w53p_315cfw3n9g9_b" width=546 border=0> </p>
<p>&nbsp;</p>
<p><img height=586 alt="" src="http://docs.google.com/File?id=dd74w53p_316gtkwrxfp_b" width=544 border=0> </p>
<p>&nbsp;</p>
<p><span>然后在项目下建立</span> lib<span>文件夹</span> ,<span>放置需要用的</span> jar<span>文件</span> ,<span>然后目录结构如下</span> </p>
<p><img height=128 alt="" src="http://docs.google.com/File?id=dd74w53p_317fgs468gm_b" width=328 border=0> </p>
<p>&nbsp;</p>
<p><span>将下载的</span> hibernate<span>解压</span> ,<span>目录结构如下</span> </p>
<p><img height=147 alt="" src="http://docs.google.com/File?id=dd74w53p_318cbjxc2dx_b" width=488 border=0> </p>
<p>&nbsp;</p>
<p><span>将这个</span> required <span>目录下的</span> jar<span>包</span> copy<span>到项目的</span> lib<span>下</span> </p>
<p><span>将 </span>hibernate3.jar<span>以及用到的数据库连结驱动包放到项目的</span> lib<span>下</span> </p>
<p><span>下载 </span>slf4j-nop-1.5.2.jar ,</p>
<p><span>也放在这个项目的</span> lib<span>下</span> ,<span>否则会出错</span> (<em>org.hibernate.HibernateException The database returned no natively generated identity value"</em> ).</p>
<p><img height=288 alt="" src="http://docs.google.com/File?id=dd74w53p_319gkph92gm_b" width=331 border=0> </p>
<p>&nbsp;</p>
<p><span>将这些</span> jar<span>包添加到项目的构建路径</span> </p>
<p>&nbsp;</p>
<p><img height=320 alt="" src="http://docs.google.com/File?id=dd74w53p_320d42jfqhk_b" width=349 border=0> </p>
<p>&nbsp;</p>
<p><span>建立 </span>com.wangyi..hibernate.demo<span>包</span> ,<span>在这个包下建立</span> User.java<span>文件</span> ,<span>类结构如下图所示</span> :</p>
<p><img height=317 alt="" src="http://docs.google.com/File?id=dd74w53p_3219rr3scch_b" width=329 border=0> </p>
<p>&nbsp;</p>
<p><span>实际上就是一个简单的</span> pojo<span>类</span> ,<span>其详细代码很如下</span> :</p>
<p><img height=913 alt="" src="http://docs.google.com/File?id=dd74w53p_322fhhb5tgt_b" width=569 border=0> </p>
<p>&nbsp;</p>
<p><span>在源文件夹下</span> , <span>下面使用新建向导给这个类建立映射配置文件</span> User.hbm.xml,<span>将这个类映射到数据库的表格上。</span> </p>
<p><img height=520 alt="" src="http://docs.google.com/File?id=dd74w53p_323hfb659ct_b" width=546 border=0> </p>
<p><span>编辑内容如下</span> :</p>
<p><img height=243 alt="" src="http://docs.google.com/File?id=dd74w53p_324dr6vmvpc_b" width=577 border=0> </p>
<p><span>其中</span> ,<span>代码中</span> <strong>com.wangyi.hibernate.demo.User</strong> <span>表示</span> ,<span>类名为</span> <strong>com.wangyi.hibernate.demo</strong> <span>包下的</span> <strong>User</strong> <span>类</span> ,<span>表为数据库中的</span> <strong>User</strong> <span>表</span> .<span>这个</span> XML<span>文件定义了对象属性映射到数据库表的关系</span> .</p>
<p>&nbsp;</p>
<p>Hibernate<span>可以使用</span> XML<span>或属性文件来进行配置，配置文件名默认为?</span> hibernate.cfg.xml?, <span>在源文件夹下，通过新建向导新建一个</span> hibernate.cfg.xml<span>文件，与</span> User.hbm.xml<span>文件在同一目录下</span> , </p>
<p><img height=520 alt="" src="http://docs.google.com/File?id=dd74w53p_325tnw96f4_b" width=544 border=0> </p>
<p>&nbsp;</p>
<p><span>内容如下：</span> </p>
<p><img height=315 alt="" src="http://docs.google.com/File?id=dd74w53p_3266dfr9sf8_b" width=576 border=0> </p>
<p>&nbsp;</p>
<p><span>建立</span> com.wangyi.hibernate.demo.test<span>包</span> ,<span>在这个包下建立测试用例 </span>TestHibernate.java:</p>
<p><img height=561 alt="" src="http://docs.google.com/File?id=dd74w53p_3277dc6xvdx_b" width=566 border=0> </p>
<p><span>类结构如下</span> :</p>
<p><img height=430 alt="" src="http://docs.google.com/File?id=dd74w53p_328fdfzh7d8_b" width=333 border=0> </p>
<p><span>具体代码如下</span> :</p>
<p><img height=726 alt="" src="http://docs.google.com/File?id=dd74w53p_329ds7zjkfw_b" width=576 border=0> </p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span>好了</span> .<span>大部分准备工作已经做好了</span> ,<span>启动</span> MySQL,<span>按照如下语句建立所要用到的库表</span> :</p>
<p><img height=232 alt="" src="http://docs.google.com/File?id=dd74w53p_330gj33zzfb_b" width=400 border=0> </p>
<p>&nbsp;</p>
<p><span>在</span> TestHibernate.java<span>文件上右键以?</span> JUnit<span>方式运行</span> .?</p>
<p>&nbsp;</p>
<p><img height=569 alt="" src="http://docs.google.com/File?id=dd74w53p_331gjn6qwcq_b" width=577 border=0> </p>
<p>&nbsp;</p>
<p><span>由于</span> ,<span>在</span> hibernate.cfg.xml<span>文件中配置了</span> </p>
<p><span><span style="FONT-SIZE: small"><font size=2><strong>true</strong> </font></span></span></p>
<p><span>所以会在控制台看到如下输出</span> :</p>
<p><img height=193 alt="" src="http://docs.google.com/File?id=dd74w53p_3325wf5x3fk_b" width=576 border=0> </p>
<p>&nbsp;</p>
<p><span>使用</span> MySQL<span>客户端工具</span> ,<span>可以看到所建立的库表中</span> ,<span>增加了</span> 10<span>条数据</span> .</p>
<p><img height=207 alt="" src="http://docs.google.com/File?id=dd74w53p_333fv2trt7g_b" width=408 border=0> </p>
<p>&nbsp;</p>
</div>
<img src ="http://www.cnitblog.com/stomic/aggbug/59916.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/stomic/" target="_blank">大话人生</a> 2009-07-07 16:37 <a href="http://www.cnitblog.com/stomic/archive/2009/07/07/59916.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VBA宏编程工资表</title><link>http://www.cnitblog.com/stomic/archive/2008/11/19/51679.html</link><dc:creator>大话人生</dc:creator><author>大话人生</author><pubDate>Wed, 19 Nov 2008 06:25:00 GMT</pubDate><guid>http://www.cnitblog.com/stomic/archive/2008/11/19/51679.html</guid><wfw:comment>http://www.cnitblog.com/stomic/comments/51679.html</wfw:comment><comments>http://www.cnitblog.com/stomic/archive/2008/11/19/51679.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/stomic/comments/commentRss/51679.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/stomic/services/trackbacks/51679.html</trackback:ping><description><![CDATA[<p>今天帮一朋友做了个excel的工资表转工资条的宏编程程序<br><br>前提：<br>需要录入50个人的工资条，且每个工资条必须具备25列数据，如图1<br><br>目的：<br>需要把如图1的工资表里的数据转做成图2的工资条的模板<br><br>（图1）<br><img height=255 alt="" src="http://www.cnitblog.com/images/cnitblog_com/stomic/3.JPG" width=1134 border=0><br><br>（图2）<br><img height=393 alt="" src="http://www.cnitblog.com/images/cnitblog_com/stomic/4.JPG" width=1223 border=0><br><br>步骤：<br>1.把图1表的数据导入一个新的excel表中，为了不破坏原表：）<br>2.在新的excel表中点击&#8216;开发工具&#8217;-&gt;&#8216;查看代码&#8217;<br>3.放入代码入当前excel的sheet表中<br>4.点击&#8216;开发工具&#8217;-&gt;&#8216;宏&#8217;-&gt;&#8216;执行&#8217;<br>5.生成工资条成功<br><br><br>VBA代码如下：<br><br>Sub 生成工资条()</p>
<p>Cells.Select</p>
<p>'选择整个表去掉表格线</p>
<p>Range("F1").Activate</p>
<p>'Selection.Borders(xlDiagonalDown).Line</p>
<p>Style = xlNone</p>
<p>Selection.Borders(xlDiagonalUp).LineStyle = xlNone</p>
<p>Selection.Borders(xlEdgeLeft).LineStyle = xlNone</p>
<p>Selection.Borders(xlEdgeTop).LineStyle = xlNone</p>
<p>Selection.Borders(xlEdgeBottom).LineStyle = xlNone</p>
<p>Selection.Borders(xlEdgeRight).LineStyle = xlNone</p>
<p>Selection.Borders(xlInsideVertical).LineStyle = xlNone</p>
<p>Selection.Borders(xlInsideHorizontal).LineStyle = xlNone</p>
<p>Rows("2:2").Select</p>
<p>'选择第2行</p>
<p>Selection.Insert Shift:=xlDown</p>
<p>'在第2行前插入一行，保持第2行</p>
<p>'为选中状态</p>
<p>num = 150</p>
<p>'总人数&#215;3，如工资表中有50人则</p>
<p>为50&#215;3即num = 150</p>
<p>col = 25</p>
<p>'工资表的栏数，如工资表有25栏则</p>
<p>'col=25</p>
<p>num1 = 4</p>
<p>Do While num1 &lt;= num</p>
<p>'循环插入空行</p>
<p>Range(Cells(num1, 1), Cells(num1, col)).Select</p>
<p>'选中第num1行的第1列到第col列</p>
<p>Selection.Insert Shift:=xlDown</p>
<p>Selection.Insert Shift:=xlDown</p>
<p>num1 = num1 + 3</p>
<p>Loop</p>
<p>Range(Cells(1, 1), Cells(1, col)).Select</p>
<p>Application.CutCopyMode = False</p>
<p>'剪切复制模式无效</p>
<p>Selection.Copy</p>
<p>'复制选择区域</p>
<p>Range("A2").Select</p>
<p>'选择A2单元格</p>
<p>ActiveSheet.Paste</p>
<p>'从A2单元格起粘贴内容</p>
<p>num2 = 5</p>
<p>Do While num2 &lt;= num</p>
<p>'循环插入标题行</p>
<p>Range(Cells(1, 1), Cells(1, col)).Select</p>
<p>Application.CutCopyMode = False</p>
<p>Selection.Copy</p>
<p>Cells(num2, 1).Select</p>
<p>ActiveSheet.Paste</p>
<p>num2 = num2 + 3</p>
<p>Loop</p>
<p>Range(Cells(2, 1), Cells(3, col)).Select</p>
<p>Application.CutCopyMode = False</p>
<p>Selection.Borders(xlDiagonalDown).LineStyle = xlNone</p>
<p>'定义表格边框线、内线样式</p>
<p>Selection.Borders(xlDiagonalUp).LineStyle = xlNone</p>
<p>With Selection.Borders(xlEdgeLeft)</p>
<p>.LineStyle = xlDouble</p>
<p>.Weight = xlThick</p>
<p>.ColorIndex = xlAutomatic</p>
<p>End With</p>
<p>With Selection.Borders(xlEdgeTop)</p>
<p>.LineStyle = xlDouble</p>
<p>.Weight = xlThick</p>
<p>.ColorIndex = xlAutomatic</p>
<p>End With</p>
<p>With Selection.Borders(xlEdgeBottom)</p>
<p>.LineStyle = xlDouble</p>
<p>.Weight = xlThick</p>
<p>.ColorIndex = xlAutomatic</p>
<p>End With</p>
<p>With Selection.Borders(xlEdgeRight)</p>
<p>.LineStyle = xlDouble</p>
<p>.Weight = xlThick</p>
<p>.ColorIndex = xlAutomatic</p>
<p>End With</p>
<p>With Selection.Borders(xlInsideVertical)</p>
<p>.LineStyle = xlDash</p>
<p>.Weight = xlThin</p>
<p>.ColorIndex = xlAutomatic</p>
<p>End With</p>
<p>With Selection.Borders(xlInsideHorizontal)</p>
<p>.LineStyle = xlDash</p>
<p>.Weight = xlThin</p>
<p>.ColorIndex = xlAutomatic</p>
<p>End With</p>
<p>Selection.Copy</p>
<p>Range(Cells(5, 1), Cells(6, col)).Select</p>
<p>Selection.PasteSpecial Paste:=xlFormats, Operation:=xlNone, SkipBlanks:=False, Transpose:=False</p>
<p>'接上行删除上行尾的连字符，复制表格线样式</p>
<p>num3 = 8</p>
<p>Do While num3 &lt;= num</p>
<p>'循环复制表格线样式</p>
<p>Range(Cells(num3, 1), Cells(num3 + 1, col)).Select</p>
<p>Selection.PasteSpecial Paste:=xlFormats, Operation:=xlNone, SkipBlanks:=False, Transpose:=False</p>
<p>num3 = num3 + 3</p>
<p>Loop</p>
<p>Rows("1:1").Select</p>
<p>'删除多余的一行</p>
<p>Selection.Delete</p>
<p>End Sub</p>
<img src ="http://www.cnitblog.com/stomic/aggbug/51679.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/stomic/" target="_blank">大话人生</a> 2008-11-19 14:25 <a href="http://www.cnitblog.com/stomic/archive/2008/11/19/51679.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[分享]最新优秀源码网站</title><link>http://www.cnitblog.com/stomic/archive/2008/08/28/48481.html</link><dc:creator>大话人生</dc:creator><author>大话人生</author><pubDate>Thu, 28 Aug 2008 09:30:00 GMT</pubDate><guid>http://www.cnitblog.com/stomic/archive/2008/08/28/48481.html</guid><wfw:comment>http://www.cnitblog.com/stomic/comments/48481.html</wfw:comment><comments>http://www.cnitblog.com/stomic/archive/2008/08/28/48481.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cnitblog.com/stomic/comments/commentRss/48481.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/stomic/services/trackbacks/48481.html</trackback:ping><description><![CDATA[<h2>[分享]最新优秀源码网站</h2>
<br>
<div class=t_msgfont id=postmessage_1056152>1.站长下载:<a href="http://down.chinaz.com/" target=_blank><u><font color=#0000ff>http://down.chinaz.com/</font></u></a> <br><br>2.CSDN下载：<a href="http://download.csdn.net/" target=_blank><u><font color=#0000ff>http://download.csdn.net</font></u></a> <br><br><font color=red>3.源码仓库：</font><a href="http://www.muchool.com/" target=_blank><font color=red><u>http://www.muchool.com</u></font></a><br><font color=red></font><br><font color=red>4..net源码：</font><a href="http://www.51aspx.com/" target=_blank><font color=red><u>http://www.51aspx.com/</u></font></a><font color=red> </font><br><font color=red></font><br><font color=red>5.无忧源码：</font><a href="http://www.5uym.com/" target=_blank><font color=red><u>http://www.5uym.com/</u></font></a><font color=red> </font><br><br>6.源码天下：<a href="http://www.pccode.net/" target=_blank><u><font color=#0000ff>http://www.pccode.net/</font></u></a><br><br>7.天新网：<a href="http://codes.21tx.com/" target=_blank><u><font color=#0000ff>http://codes.21tx.com/</font></u></a> <br><br>8.资源吧：<a href="http://www.ziyuan8.com/" target=_blank><u><font color=#0000ff>http://www.ziyuan8.com/</font></u></a><br><br>9.站长源码：<a href="http://down.cnzz.cn/" target=_blank><u><font color=#0000ff>http://down.cnzz.cn/</font></u></a> <br><br>10.源码之家：<a href="http://www.mycodes.net/" target=_blank><u><font color=#0000ff>http://www.mycodes.net/</font></u></a>&nbsp;&nbsp;<br><br>11.源码网：<a href="http://www.codepub.com/" target=_blank><u><font color=#0000ff>http://www.codepub.com/</font></u></a>&nbsp; &nbsp;<br><br>12.洪越源代码：<a href="http://www.softhy.net/" target=_blank><u><font color=#0000ff>http://www.softhy.net/</font></u></a>&nbsp;&nbsp;<br><br>13.锋网源码：<a href="http://www.fwvv.net/" target=_blank><u><font color=#0000ff>http://www.fwvv.net/</font></u></a>&nbsp; &nbsp;<br><br>14.中国源码下载站：<a href="http://www.downcode.com/" target=_blank><u><font color=#0000ff>http://www.downcode.com/</font></u></a>&nbsp; &nbsp;<br><br>15.源码天空：<a href="http://www.codesky.net/" target=_blank><u><font color=#0000ff>http://www.codesky.net/</font></u></a>&nbsp; &nbsp;<br><br>16.ASP300：<a href="http://www.asp300.com/" target=_blank><u><font color=#0000ff>http://www.asp300.com/</font></u></a>&nbsp;&nbsp;<br><br>17:中国源码中心：<a href="http://www.cncode.com/" target=_blank><u><font color=#0000ff>http://www.cncode.com/</font></u></a>&nbsp; &nbsp; <br><br>18.酷源码：<a href="http://www.kyuanma.com/" target=_blank><u><font color=#0000ff>http://www.kyuanma.com/</font></u></a><br><br><font color=red>红色为无广告网站</font></div>
<img src ="http://www.cnitblog.com/stomic/aggbug/48481.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/stomic/" target="_blank">大话人生</a> 2008-08-28 17:30 <a href="http://www.cnitblog.com/stomic/archive/2008/08/28/48481.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XMLTextWrite创建XML </title><link>http://www.cnitblog.com/stomic/archive/2008/05/16/43794.html</link><dc:creator>大话人生</dc:creator><author>大话人生</author><pubDate>Thu, 15 May 2008 18:09:00 GMT</pubDate><guid>http://www.cnitblog.com/stomic/archive/2008/05/16/43794.html</guid><wfw:comment>http://www.cnitblog.com/stomic/comments/43794.html</wfw:comment><comments>http://www.cnitblog.com/stomic/archive/2008/05/16/43794.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/stomic/comments/commentRss/43794.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/stomic/services/trackbacks/43794.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: XML 学习 1 读写XML 2 使用文档对象建模(DOM) 3 对数据集使用XML 4 使用C# 编辑XML文件 可扩展标记语言已经(XML)已经成为标记共享数据的标准。 XML文件可以用于很多方面,包括标记标记的简单数据文件和存储临时数据的简单任务, 以及将信息从一个程序和进程传递到另一个数据和进程的复杂任务。 System.Xml 包括:System.Xml.Xpath&nbsp;&nbsp...&nbsp;&nbsp;<a href='http://www.cnitblog.com/stomic/archive/2008/05/16/43794.html'>阅读全文</a><img src ="http://www.cnitblog.com/stomic/aggbug/43794.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/stomic/" target="_blank">大话人生</a> 2008-05-16 02:09 <a href="http://www.cnitblog.com/stomic/archive/2008/05/16/43794.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ASP.NET中动态生成Xml格式文档，并转换为HTML文件</title><link>http://www.cnitblog.com/stomic/archive/2008/05/16/43793.html</link><dc:creator>大话人生</dc:creator><author>大话人生</author><pubDate>Thu, 15 May 2008 16:19:00 GMT</pubDate><guid>http://www.cnitblog.com/stomic/archive/2008/05/16/43793.html</guid><wfw:comment>http://www.cnitblog.com/stomic/comments/43793.html</wfw:comment><comments>http://www.cnitblog.com/stomic/archive/2008/05/16/43793.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/stomic/comments/commentRss/43793.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/stomic/services/trackbacks/43793.html</trackback:ping><description><![CDATA[<p>程序实现功能：</p>
<p>1.读取数据，点解&#8220;获取&#8221;按钮动态生成XML格式的文档，并把生成的文档放在TEXTBOX或者生成一个XML文件。</p>
<p>2.点击&#8220;浏览&#8221;按钮，把获取到的XML格式文档，转换成HTML，在浏览器中显示。</p>
<p>&nbsp;</p>
<p>首先在ASPX对应的CS文件中引入using System.Xml;</p>
<p>&nbsp;int m = 0;&nbsp; int loop = 0;</p>
<p>//根据指定的获取深度DEPTH获取用于生成XML文档的数据<br>&nbsp;&nbsp;&nbsp; private int initData(string[] parent, string[] guid, string[] path, string[] name, ChannelCollection cc,int depth)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach (Channel channel in cc)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; parent[m] = channel.Parent.Guid;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; guid[m] = channel.Guid;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; path[m] = channel.Path;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name[m] = channel.Name;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m = m + 1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (channel.Channels.Count!=0 &amp;&amp;loop&lt;depth)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ChannelCollection c = channel.Channels;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ++loop;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; initData( parent, guid, path, name, c,depth);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return m;<br>&nbsp;&nbsp;&nbsp; } </p>
<p>&nbsp;//点击&#8220;获取XML内容&#8220;按钮执行的事件<br>&nbsp;&nbsp;&nbsp; protected void ButtonGetXml_Click(object sender, EventArgs e)<br>&nbsp;&nbsp;&nbsp; {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ChannelCollection cc = selectedChannel.Channels;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string[] parent =new string[1000];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string[] guid = new string[1000];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string[] path = new string[1000];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string[] style = new string[1000];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string[] name = new string[1000];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i=0;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int depth = int.Parse( DropDownListGetDepth.SelectedValue);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //根据指定的获取深度DEPTH获取用于生成XML文档的数据<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i=initData(parent, guid, path, name, cc,depth);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //创建XML 文档对象<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; document = new XmlDocument();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //创建XML节点元素<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XmlElement channelsElement = document.CreateElement("Channels");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; document.AppendChild(channelsElement);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int k = 1; k &lt;=i; k++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; channelsElement.AppendChild(document.CreateElement("CHANNEL"));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //根据元素节点名获取元素节点<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XmlNodeList nodelist = document.GetElementsByTagName("CHANNEL");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int size = nodelist.Count;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int k = 0; k &lt; size; k++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XmlNode node = nodelist.Item(k);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XmlElement elementNode = (XmlElement)node;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //elementNode.SetAttribute("guid",guid[k]);设置元素属性<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elementNode.AppendChild(document.CreateElement("PARENT"));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elementNode.AppendChild(document.CreateElement("GUID"));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elementNode.AppendChild(document.CreateElement("PATH"));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elementNode.AppendChild(document.CreateElement("NAME"));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XmlNodeList nodelistParent = document.GetElementsByTagName("PARENT");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int sizeParent = nodelistParent.Count;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int k = 0; k &lt; sizeParent; k++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XmlNode node = nodelistParent.Item(k);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XmlElement elementNode = (XmlElement)node;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //用初始化后的数据生成对应元素节点的文本节点<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elementNode.AppendChild(document.CreateTextNode(parent[k]));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XmlNodeList nodelistGuid = document.GetElementsByTagName("GUID");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int sizeGuid = nodelistGuid.Count;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int k = 0; k &lt; sizeGuid; k++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XmlNode node = nodelistGuid.Item(k);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XmlElement elementNode = (XmlElement)node;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elementNode.AppendChild(document.CreateTextNode(guid[k]));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XmlNodeList nodelistPath = document.GetElementsByTagName("PATH");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int sizePath = nodelistPath.Count;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int k = 0; k &lt; sizePath; k++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XmlNode node = nodelistPath.Item(k);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XmlElement elementNode = (XmlElement)node;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elementNode.AppendChild(document.CreateTextNode(path[k]));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XmlNodeList nodelistName = document.GetElementsByTagName("NAME");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int sizeName = nodelistName.Count;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int k = 0; k &lt; sizeName; k++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XmlNode node = nodelistName.Item(k);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XmlElement elementNode = (XmlElement)node;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elementNode.AppendChild(document.CreateTextNode(name[k]));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // document.Save("/icbc/newxml.xml");//可以保存为XML文件，位置在C:/icbc/newxml.xml<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //创建用于保存内容的字符串里<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StringBuilder sb = new StringBuilder();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //输出流指向字符串<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XmlWriter writer= XmlWriter.Create(sb); <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //XML文档把内容写到字符串里<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; document.WriteContentTo(writer);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; writer.Flush();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //让页面中的文本框显示XML文档内容<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TextBoxContent.Text=sb.ToString() ;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; }</p>
<p>//点击&#8221;预览&#8220;按钮，转到XML生成HTML的页面<br>&nbsp;&nbsp;&nbsp; protected void ButtonYuLAN_Click(object sender, EventArgs e)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //XmlDocument xml = new XmlDocument();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (TextBoxContent.Text == null || TextBoxContent.Text == "")<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Response.Write("&lt;script&gt;alert('请先点击获取内容');&lt;/script&gt;");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Session["xmlTextBoxContent"] = TextBoxContent.Text;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Response.Write("&lt;script&gt;window.open('PreExploerXMLMenu.aspx')&lt;/script&gt;");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; }</p>
<p>//'PreExploerXMLMenu.aspx.CS的内容如下</p>
<p>using System;<br>using System.Data;<br>using System.Configuration;<br>using System.Collections;<br>using System.Web;<br>using System.Web.Security;<br>using System.Web.UI;<br>using System.Web.UI.WebControls;<br>using System.Web.UI.WebControls.WebParts;<br>using System.Web.UI.HtmlControls;<br>using System.Xml;<br>using System.IO;<br>using System.Text;</p>
<p>public partial class Module_ChannelInfoManage_PreExploerXMLMenu : System.Web.UI.Page<br>{<br>&nbsp;&nbsp;&nbsp; protected void Page_Load(object sender, EventArgs e)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //创建XmlDisplay类的实例<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XmlDisplay XmlDisplayDemo = new XmlDisplay();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //得到XML内容，申明为字符串用于生成 StringReader<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string xmlcontent=(string )Session["xmlTextBoxContent"];<br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //生成在网页上保留静态文本的位置<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Literal LT = new Literal();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LT.Text = XmlDisplayDemo.LoadDocument(new StringReader(xmlcontent));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.Panel1.Controls.Add(LT);<br>&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; //这个类读入并处理XML文件<br>&nbsp;&nbsp;&nbsp; public class XmlDisplay</p>
<p>&nbsp;&nbsp;&nbsp; {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public string LoadDocument(StringReader sr)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XmlReader xmlReader = null;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StringBuilder html = new StringBuilder();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //创建XMLTextReader的实例。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xmlReader = XmlReader.Create(sr); <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //处理XML文件<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; html.Append(ProcessXml(xmlReader));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch (XmlException ex)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; html.Append("发生一个XML异常：" + ex.ToString());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch (Exception ex)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; html.Append("发生一个普通异常：" + ex.ToString());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; finally<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (xmlReader != null)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xmlReader.Close();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return html.ToString();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //处理XML数据的方法，用于控制生成HTML文件的格式<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private string ProcessXml(XmlReader xmlReader)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StringBuilder temp = new StringBuilder();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i = 1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp.Append("&lt;table border=1&gt;");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //XML读取器找到&#8221;NAME&#8220;的标记元素<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xmlReader.ReadToFollowing("NAME");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (i == 1) temp.Append("&lt;tr&gt;");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp.Append("&lt;td&gt;");</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //xml读取器的位置向前移动，指到 文本元素内容<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xmlReader.Read();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //读取文本元素内容到字符串中&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp.Append(xmlReader.Value);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp.Append("&lt;/td&gt;");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //一行显示10列数据<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((i%10==0)) temp.Append("&lt;/tr&gt;&lt;tr&gt;");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i++;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } while (xmlReader.ReadToFollowing("NAME"));</p>
<p><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp.Append("&lt;/tr&gt;&lt;/table&gt;");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return temp.ToString();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }//结束ProcessXML方法<br>&nbsp;&nbsp;&nbsp; }<br>}</p>
<p>&nbsp;</p>
<p>该文章转载自网络大本营：<a href="http://www.xrss.cn/Dev/DotNet/200782115914.Html">http://www.xrss.cn/Dev/DotNet/200782115914.Html</a></p>
<img src ="http://www.cnitblog.com/stomic/aggbug/43793.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/stomic/" target="_blank">大话人生</a> 2008-05-16 00:19 <a href="http://www.cnitblog.com/stomic/archive/2008/05/16/43793.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>什么是web service</title><link>http://www.cnitblog.com/stomic/archive/2007/10/24/35264.html</link><dc:creator>大话人生</dc:creator><author>大话人生</author><pubDate>Wed, 24 Oct 2007 03:47:00 GMT</pubDate><guid>http://www.cnitblog.com/stomic/archive/2007/10/24/35264.html</guid><wfw:comment>http://www.cnitblog.com/stomic/comments/35264.html</wfw:comment><comments>http://www.cnitblog.com/stomic/archive/2007/10/24/35264.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/stomic/comments/commentRss/35264.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/stomic/services/trackbacks/35264.html</trackback:ping><description><![CDATA[<table width="100%" align=center>
    <tbody>
        <tr>
            <td>你可能早就听说过Web&nbsp;service了，你也可能已经对Web&nbsp;service有一些概念了。一时间，好像所有的<a href="http://www.itisedu.com/phrase/200603021438435.html" target=_new><u><font color=#0000ff>计算机</font></u></a>期刊、书籍和网站都开始提及Web&nbsp;service。然而，当前大多数对Web&nbsp;service的介绍都没能清楚的说明Web&nbsp;service到底是什么。他们只是鼓吹Web&nbsp;service是多么多么的好，简直就像是在做广告。在本文中会讲清楚两件事：Web&nbsp;service到底是什么；在什么情况下你应该使用Web&nbsp;service。&nbsp; <br><br><strong>分布式应用<a href="http://www.itisedu.com/phrase/200604232224305.html" target=_new><u><font color=#0000ff>程序</font></u></a>和浏览器</strong>&nbsp; <br><br>研究一下当前的应用程序开发，你会发现一个绝对的倾向：人们开始偏爱基于浏览器的瘦客户应用程序。这当然不是因为瘦客户能够提供更好的用户界面，而是因为它能够避免花在桌面应用程序发布上的高成本。发布桌面应用程序成本很高，一半是因为应用程序安装和配置的问题，另一半是因为客户和服务器之间通信的问题。&nbsp; <br><br>传统的Windows富客户应用程序使用<a href="http://www.itisedu.com/phrase/200604152041495.html" target=_new><u><font color=#0000ff>DCOM</font></u></a>来与服务器进行通信和调用远程<a href="http://www.itisedu.com/phrase/200603090845215.html" target=_new><u><font color=#0000ff>对象</font></u></a>。配置好DCOM使其在一个大型的网络中正常工作将是一个极富挑战性的工作，同时也是许多IT工程师的噩梦。事实上，许多IT工程师宁愿忍受浏览器所带来的功能限制，也不愿在局域网上去运行一个DCOM。在我看来，结果就是一个发布容易，但开发难度大而且用户界面极其受限的应用程序。极端的说，就是你花了更多的资金和时间，却开发出从用户看来功能更弱的应用程序。不信？问问你的会计师对新的基于浏览器的会计<a href="http://www.itisedu.com/phrase/200604232134205.html" target=_new><u><font color=#0000ff>软件</font></u></a>有什么想法：绝大多数商用程序用户希望使用更加友好的Windows用户界面。&nbsp; <br><br>关于<a href="http://www.itisedu.com/phrase/200603082208195.html" target=_new><u><font color=#0000ff>客户端</font></u></a>与服务器的通信问题，一个完美的解决方法是使用HTTP协议来通信。这是因为任何运行Web浏览器的机器都在使用HTTP协议。同时，当前许多防火墙也配置为只允许HTTP连接。&nbsp; <br><br>许多商用程序还面临另一个问题，那就是与其他程序的互操作性。如果所有的应用程序都是使用COM或.NET语言写的，并且都运行在Windows平台上，那就天下太平了。然而，事实上大多数商业数据仍然在大型主机上以非关系<a href="http://www.itisedu.com/phrase/200602282323195.html" target=_new><u><font color=#0000ff>文件</font></u></a>(VSAM)的形式存放，并由COBOL语言编写的大型机程序访问。而且，目前还有很多商用程序继续在使用C++、Java、Visual&nbsp; <br><br>Basic和其他各种各样的语言编写。现在，除了最简单的程序之外，所有的应用程序都需要与运行在其他异构平台上的应用程序集成并进行数据交换。这样的任务通常都是由特殊的方法，如文件传输和分析，<a href="http://www.itisedu.com/phrase/200603090938465.html" target=_new><u><font color=#0000ff>消息</font></u></a>队列，还有仅适用于某些情况的的<a href="http://www.itisedu.com/phrase/200604241228185.html" target=_new><u><font color=#0000ff>API</font></u></a>，如IBM的"高级程序到程序交流(APPC)"等来完成的。在以前，没有一个应用程序通信标准，是独立于平台、组建模型和编程语言的。只有通过Web&nbsp; <br><br>Service，客户端和服务器才能够自由的用HTTP进行通信，不论两个程序的平台和编程语言是什么。&nbsp; <br><br><strong>什么是Web&nbsp;Service</strong>&nbsp; <br><br>对这个问题，我们至少有两种答案。从表面上看，Web&nbsp;service&nbsp;就是一个应用程序，它向外界暴露出一个能够通过Web进行调用的API。这就是说，你能够用编程的方法通过Web来调用这个应用程序。我们把调用这个Web&nbsp;service&nbsp;的应用程序叫做客户。例如，你想创建一个Web&nbsp;service&nbsp;，它的作用是返回当前的天气情况。那么你可已建立一个ASP页面，它接受邮政编码作为查询字符串，然后返回一个由逗号隔开的字符串，包含了当前的气温和天气。要调用这个ASP页面，客户端需要发送下面的这个HTTP&nbsp;GET请求：&nbsp; <br><br>http://host.company.com/weather.asp?zipcode=20171&nbsp; <br><br>返回的数据就应该是这样：&nbsp; <br><br>21,晴&nbsp; <br><br>这个ASP页面就应该可以算作是Web&nbsp;service&nbsp;了。因为它基于HTTP&nbsp;GET请求，暴露出了一个可以通过Web调用的API。当然，Web&nbsp;service&nbsp;还有更多的东西。&nbsp; <br><br>下面是对Web&nbsp;service&nbsp;更精确的解释：&nbsp;Web&nbsp;services是建立可互操作的分布式应用程序的新平台。作为一个Windows程序员，你可能已经用COM或DCOM建立过基于<a href="http://www.itisedu.com/phrase/200603302222545.html" target=_new><u><font color=#0000ff>组件</font></u></a>的分布式应用程序。COM是一个非常好的组件技术，但是我们也很容易举出COM并不能满足要求的情况。&nbsp; <br><br>Web&nbsp;service平台是一套标准，它定义了应用程序如何在Web上实现互操作性。你可以用任何你喜欢的语言，在任何你喜欢的平台上写Web&nbsp;service&nbsp;，只要我们可以通过Web&nbsp;service标准对这些服务进行查询和访问。&nbsp; <br><br><strong>新平台</strong>&nbsp; <br><br>Web&nbsp;service平台需要一套协议来实现分布式应用程序的创建。任何平台都有它的数据表示方法和<a href="http://www.itisedu.com/phrase/200603051002565.html" target=_new><u><font color=#0000ff>类型</font></u></a>系统。要实现互操作性，Web&nbsp;service平台必须提供一套标准的<a href="http://www.itisedu.com/phrase/200603090857555.html" target=_new><u><font color=#0000ff>类</font></u></a>型系统，用于沟通不同平台、编程语言和组件模型中的不同类型系统。在传统的分布式系统中，基于界面(interface)的平台提供了一些方法来描述界面、方法和参数（译注：如COM和COBAR中的IDL语言）。同样的，Web&nbsp;service平台也必须提供一种标准来描述Web&nbsp;service，让客户可以得到足够的信息来调用这个Web&nbsp; <br><br>service。最后，我们还必须有一种方法来对这个Web&nbsp;service进行远程调用。这种方法实际是一种<a href="http://www.itisedu.com/phrase/200604241405415.html" target=_new><u><font color=#0000ff>远程过程调用</font></u></a>协议(RPC)。为了达到互操作性，这种RPC协议还必须与平台和编程语言无关。下面几个小节就简要介绍了组成Web&nbsp;service平台的这三个技术。&nbsp; <br><br><strong><a href="http://www.itisedu.com/phrase/200604231236585.html" target=_new><u><font color=#0000ff>XML</font></u></a>和XSD</strong>&nbsp; <br><br>可扩展的标记语言(XML)是Web&nbsp;service平台中表示数据的基本格式。除了易于建立和易于分析外，XML主要的优点在于它既是平台无关的，又是厂商无关的。无关性是比技术优越性更重要的：软件厂商是不会选择一个由竞争对手所发明的技术的。&nbsp; <br><br>XML解决了数据表示的问题，但它没有定义一套标准的数据类型，更没有说怎么去扩展这套数据类型。例如，整形数到底代表什么？16位，32位，还是64位？这些细节对实现互操作性都是很重要的。W3C制定的XML&nbsp;Schema(XSD)就是专门解决这个问题的一套标准。它定义了一套标准的数据类型，并给出了一种语言来扩展这套数据类型。Web&nbsp;service平台就是用XSD来作为其数据类型系统的。当你用某种语言(如VB.NET或C#)来构造一个Web&nbsp;service时，为了符合Web&nbsp;service标准，所有你使用的数据类型都必须被转换为XSD类型。你用的工具可能已经自动帮你完成了这个转换，但你很可能会根据你的需要修改一下转换过程。在第二章中，我们将深入XSD，学习怎样转换自定义的数据类型(例如类)到XSD的类型。&nbsp; <br><br><strong><a href="http://www.itisedu.com/phrase/200603021816435.html" target=_new><u><font color=#0000ff>SOA</font></u></a>P</strong>&nbsp; <br><br>Web&nbsp;service建好以后，你或者其他人就会去调用它。简单对象访问协议(SOAP)提供了标准的RPC方法来调用Web&nbsp;service。实际上，SOAP在这里有点用词不当：它意味着下面的Web&nbsp;service是以对象的方式表示的，但事实并不一定如此：你完全可以把你的Web&nbsp;service写成一系列的C函数，并仍然使用SOAP进行调用。SOAP规范定义了SOAP消息的格式，以及怎样通过HTTP协议来使用SOAP。SOAP也是基于XML和XSD的，XML是SOAP的数据编码方式。第三章我们会讨论SOAP，并结识SOAP消息的各种元素。&nbsp; <br><br><strong>WSDL</strong>&nbsp; <br><br>你会怎样向别人介绍你的Web&nbsp;service有什么功能，以及每个函数调用时的参数呢？你可能会自己写一套文档，你甚至可能会口头上告诉需要使用你的Web&nbsp;service的人。这些非正式的方法至少都有一个严重的问题：当程序员坐到<a href="http://www.itisedu.com/phrase/200604231234155.html" target=_new><u><font color=#0000ff>电脑</font></u></a>前，想要使用你的Web&nbsp;service的时候，他们的工具(如Visual&nbsp;Studio)无法给他们提供任何帮助，因为这些工具根本就不了解你的Web&nbsp; <br><br>service。解决方法是：用机器能阅读的方式提供一个正式的描述文档。Web&nbsp;service描述语言(WSDL)就是这样一个基于XML的语言，用于描述Web&nbsp;service及其函数、参数和返回值。因为是基于XML的，所以WSDL既是机器可阅读的，又是人可阅读的，这将是一个很大的好处。一些最新的开发工具既能根据你的Web&nbsp;service生成WSDL文档，又能导入WSDL文档，生成调用相应Web&nbsp;service的代码。 </td>
        </tr>
        <tr>
            <td align=right>来源：赛迪网论坛 </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.cnitblog.com/stomic/aggbug/35264.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/stomic/" target="_blank">大话人生</a> 2007-10-24 11:47 <a href="http://www.cnitblog.com/stomic/archive/2007/10/24/35264.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ASP.NET中如何调用存储过程</title><link>http://www.cnitblog.com/stomic/archive/2007/09/05/33025.html</link><dc:creator>大话人生</dc:creator><author>大话人生</author><pubDate>Wed, 05 Sep 2007 14:51:00 GMT</pubDate><guid>http://www.cnitblog.com/stomic/archive/2007/09/05/33025.html</guid><wfw:comment>http://www.cnitblog.com/stomic/comments/33025.html</wfw:comment><comments>http://www.cnitblog.com/stomic/archive/2007/09/05/33025.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/stomic/comments/commentRss/33025.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/stomic/services/trackbacks/33025.html</trackback:ping><description><![CDATA[用ASP.NET与SQL SERVER可是缘份最好了，稍大的程序一般第一先考虑的是SQLSERVER，只是一些很考虑经济的才使用ACCESS等了。用SQL SERVER，为了使数据库的效率更好，一般都会才取存储过程，因存储过程执行速度快，并且可以实现一些高级的查询等功能。比如传入一些数据参数，但执行的SQL过程可能不同等。<br>　　<br>下面就来个例子，建立一新的角色，要求角色的名字不能重复，以下是一存储过程。<br>CREATE PROCEDURE sp_AccountRole_Create@CategoryID int,<br>　　@RoleName nvarchar(10),<br>　　@Description nvarchar(50),<br>　　@RoleID int output<br>　　AS<br>　　DECLARE @Count int<br>　　<br>　　-- 查找是否有相同名称的记录<br>　　SELECT @Count = Count(RoleID) FROM Account_Role WHERE<br>　　RoleName = @RoleName<br>　　IF @Count = 0<br>　　INSERT INTO Account_Role<br>　　(CategoryID, RoleName, Description) valueS<br>　　(@CategoryID, @RoleName, @Description)<br>　　SET @RoleID = @@IDENTITY<br>　　RETURN 1GO<br>　　<br>　　执行存储过程的C#过程：<br>　　<br>　　SqlConnection DbConnection = new SqlConnection(mConnectionString);&nbsp; <br>　　SqlCommand command = new SqlCommand( "sp_AccountRole_Create", DbConnection );<br>　　DbConnection.Open(connectString);<br>　　// 设置SqlCommand的属性为存储过程<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; command.CommandType = CommandType.StoredProcedure;<br>　　command.Parameters.Add("@CategoryID", SqlDbType.Int, 4);<br>　　command.Parameters.Add("@RoleName", SqlDbType.NVarChar, 10);<br>　　command.Parameters.Add("@Description", SqlDbType.NVarChar, 50);<br>　　command.Parameters.Add("@RoleID", SqlDbType.Int, 4);<br>　　// 返回值command.Parameters.Add("Returnvalue",SqlDbType.Int,<br>　　4,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Size<br>　　ParameterDirection.Returnvalue,<br>　　false,&nbsp;&nbsp;&nbsp; // is nullable　　　　　　<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // byte precision<br>　　0,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // byte scale　　　　　　<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string.Empty,DataRowVersion.Default,null );<br>　　command.parameters["@CategoryID"].value = permission.CategoryID;<br>　　command.parameters["@RoleName"].value = permission.PermissionName;<br>　　command.parameters["@Description"].value = permission.Description;<br>　　// 可以返回新的ID值<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; command.parameters["@RoleID"].Direction = ParameterDirection.Output;&nbsp; <br>　　int rowsAffected = command.ExecuteNonQuery();<br>　　int result = command.parameters["Returnvalue"].value;int newID = command.parameters["@RoleID"].value;<br>　　<br>　　功能挺强的吧，可以得到三个值，分别是行影响值，存储过程返回值，新的ID值。 <br>
<img src ="http://www.cnitblog.com/stomic/aggbug/33025.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/stomic/" target="_blank">大话人生</a> 2007-09-05 22:51 <a href="http://www.cnitblog.com/stomic/archive/2007/09/05/33025.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>跟我学XSL（四）－脚本与XSL的结合及应用</title><link>http://www.cnitblog.com/stomic/archive/2007/07/31/30958.html</link><dc:creator>大话人生</dc:creator><author>大话人生</author><pubDate>Mon, 30 Jul 2007 19:15:00 GMT</pubDate><guid>http://www.cnitblog.com/stomic/archive/2007/07/31/30958.html</guid><wfw:comment>http://www.cnitblog.com/stomic/comments/30958.html</wfw:comment><comments>http://www.cnitblog.com/stomic/archive/2007/07/31/30958.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/stomic/comments/commentRss/30958.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/stomic/services/trackbacks/30958.html</trackback:ping><description><![CDATA[有时，我们可能会希望XML文档输出时能对其中内容加上一些统计信息或者如编号什么的，利用前面的知识就不太容易实现了。今天将介绍两个新元素&lt;xsl:eval&gt;与&lt;xsl:script&gt;，使我们能轻松处理这个难题。
<p>&lt;xsl:eval&gt;</p>
<p>　　含义：计算脚本表达式，输出一个文本字符串。</p>
<p>　　语法：</p>
<p>&lt;xsl:eval language="language-name"&gt;</p>
<p>　　属性：</p>
<p>　　language ── 规定所用脚本语言的名字，可用的属性有"JavaScript"、"JScript"、"VBScript"、"VBS"等，缺省为"JScript"。</p>
<p>&lt;xsl:script&gt;</p>
<p>　　含义：声明全局变量或定义函数。</p>
<p>　　语法：</p>
<p>&lt;xsl:script language="language-name"&gt;</p>
<p>　　属性：同&lt;xsl:eval&gt;</p>
<p><br>　　示例：</p>
<p>　　不知大家对于第四期《跟我学XML》中的例子是否还有印象？其中的XML文档并没有对简历编号，但输出中却加上了大写的罗马数字序号。今天将再举一稍为复杂一些的例子：</p>
<p>　　假如我们编写一份年终生产统计表，其中需要小计一项，常规的作法是事先将其算出来，现在不必了，我们可以只给出单项统计，显示时再统计小计一项。请找出《跟我学XML》的第四期，XML文件不必修改，对XSL文件的修改如下：</p>
<p>&lt;?xml version="1.0" encoding="GB2312"?&gt;<br>&lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl"&gt;</p>
<p>&lt;xsl:template match="/"&gt;<br>&lt;HTML&gt;&lt;HEAD&gt;&lt;TITLE&gt;1999年生产统计&lt;/TITLE&gt;&lt;/HEAD&gt; <br>&lt;BODY&gt;&lt;xsl:apply-templates select="document"/&gt;&lt;/BODY&gt;<br>&lt;/HTML&gt;<br>&lt;/xsl:template&gt;</p>
<p>&lt;xsl:template match="document"&gt;<br>&lt;H3&gt;1999年生产统计&lt;/H3&gt; <br>&lt;TABLE border="1" cellspacing="0"&gt; <br>&lt;TH&gt;班组&lt;/TH&gt;<br>&lt;TH&gt;一季度&lt;/TH&gt;<br>&lt;TH&gt;二季度&lt;/TH&gt;<br>&lt;TH&gt;三季度&lt;/TH&gt;<br>&lt;TH&gt;四季度&lt;/TH&gt;<br>&lt;xsl:apply-templates select="report"/&gt;<br><strong><br>&lt;TR&gt;&lt;TD&gt;小计&lt;/TD&gt;<br>&lt;TD&gt;&lt;xsl:eval&gt;total(this,"q1")&lt;/xsl:eval&gt;&lt;/TD&gt;<br>&lt;TD&gt;&lt;xsl:eval&gt;total(this,"q2")&lt;/xsl:eval&gt;&lt;/TD&gt;<br>&lt;TD&gt;&lt;xsl:eval&gt;total(this,"q3")&lt;/xsl:eval&gt;&lt;/TD&gt;<br>&lt;TD&gt;&lt;xsl:eval&gt;total(this,"q4")&lt;/xsl:eval&gt;&lt;/TD&gt;<br>&lt;/TR&gt;</strong><br><br>&lt;/TABLE&gt;<br><strong><br>&lt;xsl:script&gt;<br>function total(node,q)<br>{<br>　　temp=0; <br>　　mark='/document/report/'+q;<br>　　v=node.selectNodes(mark);<br>　　for(t=v.nextNode();t;t=v.nextNode())<br>　　{<br>　　　　temp+=Number(t.text);<br>　　}<br>　　return temp; //小计值<br>}<br>&lt;/xsl:script&gt;<br></strong><br>&lt;/xsl:template&gt;<br><br>&lt;xsl:template match="report"&gt;<br>&lt;TR&gt;<br>&lt;TD&gt;&lt;xsl:value-of select="class"/&gt;&lt;/TD&gt;<br>&lt;TD&gt;&lt;xsl:apply-templates select="q1"/&gt;&lt;/TD&gt;<br>&lt;TD&gt;&lt;xsl:apply-templates select="q2"/&gt;&lt;/TD&gt;<br>&lt;TD&gt;&lt;xsl:apply-templates select="q3"/&gt;&lt;/TD&gt;<br>&lt;TD&gt;&lt;xsl:apply-templates select="q4"/&gt;&lt;/TD&gt;<br>&lt;/TR&gt;<br>&lt;/xsl:template&gt;</p>
<p>&lt;xsl:template match="q1|q2|q3|q4"&gt;<br>&lt;!--此处测试产量，如小于等于20则添加一STYLE属性color，其值为red（红色）--&gt; <br>&lt;xsl:if test=".[value() $le$ 20]"&gt; <br>&lt;xsl:attribute name="style"&gt;color:red&lt;/xsl:attribute&gt;<br>&lt;/xsl:if&gt;<br>&lt;xsl:value-of/&gt;<br>&lt;/xsl:template&gt;</p>
<p>&lt;/xsl:stylesheet&gt;<br><br></p>
<div align=center><img height=180 alt="" src="http://www.blueidea.com/articleimg/2004/04/1798/0007.gif" width=262 border=0><br><span class=pt9>上例在浏览器中的样子(IE5.0或更新版本)</span><br><br></div>
<p>　　说明：</p>
<p>　　注意到执行结果的变化了吗？黑体部分为添加部分，注意添加部分分为两部分，&lt;xsl:script&gt;&lt;/xsl:script&gt;必须置于&lt;/TABLE&gt;之后，切记。</p>
<p>　　selectNodes() ── 是XMLDOMObject的一个方法，返回文档中所有满足条件的结点的集合，条件与&lt; xsl:for-each &gt;和select属性的取值采用同样的写法，可以加筛选、下标等限制，如寻找一季度产量大于等于50的班组：</p>
<p>/document/report/q1[value() $ge$ 50]</p>
<p>　　以上写法还有一个更简单的写法：</p>
<p>//q1[value()$ge$50]</p>
<p>　　//表示从根结点出发遍历所有结点，寻找满足条件的结点，如果文档内有同名但意义不同的结点则不能用此种方法，非不得已不建议使用。以此为例，如果希望统计年总产量，则可以下述字符串寻找结点（建议使用最后一种，此种描述将精确找到需要汇总的数据）：</p>
<p>//*[value()$gt$0] 或 //(q1|q2|q3|q4) 或 /document/report/(q1|q2|q3|q4)</p>
<p>　　nextNode() ── 返回结点集中的下一个结点</p>
<p>　　Number() ── 将提供的参数转换为数值</p>
<p><br>　　下期介绍XSL函数2，用于&lt;xsl:script&gt;及&lt;xsl:eval&gt;中，以及&lt;xsl:if&gt;和&lt;xsl:when&gt;的expr属性。建议读者熟悉JavaScript、JScript、VBScript中至少一种，否你能用XSL完成的工作将十分有限。由于篇幅关系，此处不作详细介绍。</p>
&nbsp; 
<img src ="http://www.cnitblog.com/stomic/aggbug/30958.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/stomic/" target="_blank">大话人生</a> 2007-07-31 03:15 <a href="http://www.cnitblog.com/stomic/archive/2007/07/31/30958.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>跟我学XSL（三）－XSL函数 </title><link>http://www.cnitblog.com/stomic/archive/2007/07/31/30957.html</link><dc:creator>大话人生</dc:creator><author>大话人生</author><pubDate>Mon, 30 Jul 2007 19:14:00 GMT</pubDate><guid>http://www.cnitblog.com/stomic/archive/2007/07/31/30957.html</guid><wfw:comment>http://www.cnitblog.com/stomic/comments/30957.html</wfw:comment><comments>http://www.cnitblog.com/stomic/archive/2007/07/31/30957.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/stomic/comments/commentRss/30957.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/stomic/services/trackbacks/30957.html</trackback:ping><description><![CDATA[本期学习XSL样式方法，即可用于XSL元素&lt;xsl:for-each&gt;、&lt;xsl:value-of&gt;、&lt;xsl:template&gt;的select属性、&lt;xsl:apply-templates&gt;的match属性、&lt;xsl:if&gt;、&lt;xsl:when&gt;的test属性中，对元素的范围进行筛选，从而提供更大的灵活性。
<p><br>　　XML与DHTML（动态HTML）一样，这些节点都是一个个对象，而且这些对象都是有层次的，从根节点开始构成一颗层次清淅的树状结构，这就形成了文档对象模型DOM(Document Object Model)，通过对象的属性、方法来达到访问控制XML节点的目的。</p>
<p><br>　　我们这里不打算就XML的DOM逐一详细阐述，因为这完全可以写成一个篇幅较多的教程，我们先就一些常见的方法作一些讨论，以期对DOM的对象方法有一个大致的了解。</p>
<p>　　注：从本期开始，所有示例不再提供完整源代码，如有不明白之处，请仔细阅读前面七期、并动手练手。</p>
<p>　　一、end()</p>
<p>　　含义：返回集合中最后一个元素。</p>
<p>　　示例：输出最后一份简历</p>
<p>　　假定XML文件格式为：</p>
<p>&#8230;&#8230;&lt;resume&gt;&#8230;&lt;/resume&gt;&#8230;&#8230;&lt;resume&gt;&#8230;&lt;/resume&gt;&#8230;&#8230;</p>
<p>　　相应XSL文件内容为：</p>
<p>&lt;xsl:for-each select="resume[end()]"&gt;&#8230;&#8230;&lt;/xsl:for-each&gt;</p>
<p>　　或：</p>
<p>&lt;xsl:templates match="resume[end()]"&gt;&#8230;&#8230;&lt;/xsl:templates&gt;</p>
<p>　　或：</p>
<p>&lt;xsl:apply-template select="resume[end()]"&gt;&#8230;&#8230;&lt;/xsl:apply-template&gt;</p>
<p>　　二、index()</p>
<p>　　含义：返回该元素在集合中的位置，返回值是一整数，其中第一个元素返回0。</p>
<p>　　示例：返回前面三份简历。</p>
<p>resume[index()$le$3]</p>
<p>　　注意：index()是与父元素相关的，请看下例：</p>
<p>&lt;x&gt;<br>&lt;y/&gt;<br>&lt;y/&gt;<br>&lt;/x&gt;<br>&lt;x&gt;<br>&lt;y/&gt;<br>&lt;y/&gt;<br>&lt;/x&gt;</p>
<p>　　返回所有&lt;x&gt;中的第一个&lt;y&gt;</p>
<p>x/y[index()=0] 或x/y[0]</p>
<p>　　三、nodeName()</p>
<p>　　含义：返回元素的名字，即标记名。</p>
<p>　　示例：选择任意元素，假如其名字（即标记名）等于"name"：</p>
<p>*[nodeName()='name'] 或 *[name]</p>
<p>　　四、number()</p>
<p>　　含义：将值转换为数值形式，如果不是数值则返回空，要求参数。</p>
<p>　　示例：年龄(age)小于30岁的人的简历(resume)：</p>
<p>resume[number(age)$lt$30] 或 resume[age$lt$30]</p>
<p>　　五、nodeType()</p>
<p>　　含义：返回结点类型，结果为是数值。以下是返回值列表：<br><br></p>
<table style="FONT-SIZE: 12px" cellSpacing=1 cellPadding=0 width=500 align=center border=0>
    <tbody>
        <tr>
            <td width=209 bgColor=#000000 height=25><font color=#ffffff>&nbsp;结点类型</font></td>
            <td width=85 bgColor=#000000><font color=#ffffff>&nbsp;结点类型值</font></td>
            <td width=202 bgColor=#000000><font color=#ffffff>&nbsp;结点的字符形式描述</font></td>
        </tr>
        <tr>
            <td width=209 bgColor=#cccccc height=25>&nbsp;Element</td>
            <td width=85 bgColor=#cccccc>&nbsp;1</td>
            <td width=202 bgColor=#cccccc>&nbsp;'element'</td>
        </tr>
        <tr>
            <td width=209 bgColor=#eeeeee height=25>&nbsp;Element Attribute</td>
            <td width=85 bgColor=#eeeeee>&nbsp;2</td>
            <td width=202 bgColor=#eeeeee>&nbsp;'attribute'</td>
        </tr>
        <tr bgColor=#cccccc>
            <td width=209 height=25>&nbsp;Markup-Delimited Region of Text</td>
            <td width=85>&nbsp;3</td>
            <td width=202>&nbsp;'text'</td>
        </tr>
        <tr>
            <td width=209 bgColor=#eeeeee height=25>&nbsp;Processing Instruction</td>
            <td width=85 bgColor=#eeeeee>&nbsp;7</td>
            <td width=202 bgColor=#eeeeee>&nbsp;'processing_instruction'</td>
        </tr>
        <tr bgColor=#cccccc>
            <td width=209 height=25>&nbsp;Comment</td>
            <td width=85>&nbsp;8</td>
            <td width=202>&nbsp;'comment'</td>
        </tr>
        <tr>
            <td width=209 bgColor=#eeeeee height=25>&nbsp;Document Entity</td>
            <td width=85 bgColor=#eeeeee>&nbsp;9</td>
            <td width=202 bgColor=#eeeeee>&nbsp;'document'</td>
        </tr>
    </tbody>
</table>
<p>　　六、value()</p>
<p>　　含义：返回元素或属性的值。</p>
<p>　　示例：value()是元素或属性的缺省方法，以下表示是等价：</p>
<p>name!value()="NAME" 与 name="NAME"<br><br>@attr="attribute_value" 与 @attr="attribute_value"</p>
<p>　　注：@是属性前缀，@attr表示是属性attr</p>
<p>　　七、attribute()</p>
<p>　　含义：返回所有属性结点的集合，等价于"@*"。</p>
<p>　　示例：寻找所有的resume元素，满足条件至少有一个属性的值为"ABC"：</p>
<p>resume[$any$attribute()='ABC'] 或 resume[$any$@*='ABC']</p>
<p>　　寻找所有的resume元素，满足条件至少有一个子元素有一个属性的值为"ABC"：</p>
<p>resume[$any$*/attribute()='ABC'] 或 resume[$any$*/@*='ABC']</p>
<p>　　八、comment()</p>
<p>　　含义：返回所有注释结点。</p>
<p>　　示例：</p>
<p>resume[$any$comment()='禹希初的简历']</p>
<p>　　表示寻找含有注释语句：&lt;!--禹希初的简历--&gt;的&lt;resume&gt;元素。</p>
<p>　　九、cdata()</p>
<p>　　含义：返回所有CDATA类型的结点的集合。</p>
<p>　　示例：</p>
<p>resume[$any$cdata()='禹希初的简历']</p>
<p>　　表示寻找含有下述语句（必须是直接子结点）&lt;![CDATA[禹希初的简历]]&gt;的&lt;resume&gt;元素。</p>
<p>　　十、node()</p>
<p>　　含义：返回当前上下文环境中除根结点和属性结点以外的所有结点的集合，等价于：</p>
<p>"*|pi()|comment()|text()"</p>
<p>　　示例：寻找所有元素resume，其最后一个结点的名字为"skill"：</p>
<p>resume[node()[end()]!nodeName()='skill']</p>
<p>　　寻找所有resume元素的第一个结点：resume/node()[0]。</p>
<p>　　十一、textnode()</p>
<p>　　含义：返回所有文本类型的结点的集合。</p>
<p>　　示例：寻找每一个p元素的第二个文本结点：</p>
<p>p/textnode(1) 或 p!textnode(1)</p>
<p>　　十二、text()</p>
<p>　　含义：返回所有表示文本字符串的结点的集合，等价于"cdata()|textnode()"。</p>
<p>　　本期的内容就介绍至此，另有一个函数date()在本人的机器上一试就发生错误使浏览器自动关闭，还有一个函数pi()本人尚未找到适当的应用方法，就不介绍了，下期将讲述如何XSL中使用脚本。</p>
&nbsp; 
<img src ="http://www.cnitblog.com/stomic/aggbug/30957.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/stomic/" target="_blank">大话人生</a> 2007-07-31 03:14 <a href="http://www.cnitblog.com/stomic/archive/2007/07/31/30957.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>跟我学XSL（二） -XSL的运算符</title><link>http://www.cnitblog.com/stomic/archive/2007/07/31/30956.html</link><dc:creator>大话人生</dc:creator><author>大话人生</author><pubDate>Mon, 30 Jul 2007 19:13:00 GMT</pubDate><guid>http://www.cnitblog.com/stomic/archive/2007/07/31/30956.html</guid><wfw:comment>http://www.cnitblog.com/stomic/comments/30956.html</wfw:comment><comments>http://www.cnitblog.com/stomic/archive/2007/07/31/30956.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/stomic/comments/commentRss/30956.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/stomic/services/trackbacks/30956.html</trackback:ping><description><![CDATA[表一、运算符与特殊字符
<table style="FONT-SIZE: 12px" cellSpacing=0 cellPadding=0 width=500 align=center border=0>
    <tbody>
        <tr>
            <td width=67 bgColor=#666666 height=25>&nbsp;<font color=#ffffff>运算符</font></td>
            <td width=10 bgColor=#000000 height=25>&nbsp;</td>
            <td width=427 bgColor=#000000><font color=#ffffff>描述</font></td>
        </tr>
        <tr>
            <td width=67 bgColor=#eeeeee height=35>
            <div align=center>/</div>
            </td>
            <td width=10 bgColor=#cccccc height=35>&nbsp;</td>
            <td width=427 bgColor=#cccccc>选择子元素，返回左侧元素的直接子元素；如果"/"位于最左侧表示选择根结点的直接子元素</td>
        </tr>
        <tr bgColor=#f0f0f0>
            <td width=67 height=35>
            <div align=center>//</div>
            </td>
            <td width=10 bgColor=#eeeeee height=25>&nbsp;</td>
            <td width=427 bgColor=#eeeeee>递归下降，不论深度，搜索指定的元素；如果位于最左侧表示从根结点出发递归下降搜索指定元素</td>
        </tr>
        <tr>
            <td width=67 bgColor=#eeeeee height=35>
            <div align=center><strong><font face="Verdana, Arial, Helvetica, sans-serif">.</font></strong></div>
            </td>
            <td width=10 bgColor=#cccccc height=25>&nbsp;</td>
            <td width=427 bgColor=#cccccc>表示当前元素</td>
        </tr>
        <tr bgColor=#f0f0f0>
            <td width=67 height=35>
            <div align=center>*</div>
            </td>
            <td width=10 bgColor=#eeeeee height=25>&nbsp;</td>
            <td width=427 bgColor=#eeeeee>通配符，选择任意元素，不考虑名字</td>
        </tr>
        <tr>
            <td width=67 bgColor=#eeeeee height=35>
            <div align=center>@</div>
            </td>
            <td width=10 bgColor=#cccccc height=25>&nbsp;</td>
            <td width=427 bgColor=#cccccc>
            <p>&nbsp;</p>
            <p>取得属性值，作为属性名的前缀</p>
            </td>
        </tr>
        <tr bgColor=#f0f0f0>
            <td width=67 height=35>
            <div align=center>@*</div>
            </td>
            <td width=10 bgColor=#eeeeee height=25>&nbsp;</td>
            <td width=427 bgColor=#eeeeee>
            <p>&nbsp;</p>
            <p>通配符，选择任意属性，不考虑名字</p>
            </td>
        </tr>
        <tr>
            <td width=67 bgColor=#eeeeee height=35>
            <div align=center><font face="Verdana, Arial, Helvetica, sans-serif"><strong>:</strong></font></div>
            </td>
            <td width=10 bgColor=#cccccc height=25>&nbsp;</td>
            <td width=427 bgColor=#cccccc>名字作用范围分隔符，将名字作用范围前缀与元素或属性名分隔开来</td>
        </tr>
        <tr bgColor=#f0f0f0>
            <td width=67 height=35>
            <div align=center><font face="Verdana, Arial, Helvetica, sans-serif"><strong>!*</strong></font></div>
            </td>
            <td width=10 bgColor=#eeeeee height=25>&nbsp;</td>
            <td width=427 bgColor=#eeeeee>在相关节点上应用指定方法</td>
        </tr>
        <tr>
            <td width=67 bgColor=#eeeeee height=35>
            <div align=center>()*</div>
            </td>
            <td width=10 bgColor=#cccccc height=25>&nbsp;</td>
            <td width=427 bgColor=#cccccc>分组，明确指定优先顺序</td>
        </tr>
        <tr bgColor=#f0f0f0>
            <td width=67 height=35>
            <div align=center>[]</div>
            </td>
            <td width=10 bgColor=#eeeeee height=25>&nbsp;</td>
            <td width=427 bgColor=#eeeeee>应用过滤样式</td>
        </tr>
        <tr>
            <td width=67 bgColor=#eeeeee height=35>
            <div align=center>[]*</div>
            </td>
            <td width=10 bgColor=#cccccc height=25>&nbsp;</td>
            <td width=427 bgColor=#cccccc>下标运算符，用于在集合中指示元素</td>
        </tr>
    </tbody>
</table>
<p>　　表二、逻辑运算符</p>
<table style="FONT-SIZE: 12px" cellSpacing=0 cellPadding=0 width=500 align=center border=0>
    <tbody>
        <tr>
            <td width=114 bgColor=#666666 height=25>&nbsp;<font color=#ffffff>可选方式</font></td>
            <td width=10 bgColor=#000000 height=25>&nbsp;</td>
            <td width=368 bgColor=#000000><font color=#ffffff>描述</font></td>
        </tr>
        <tr>
            <td width=114 bgColor=#eeeeee height=25>
            <div align=center>and $and$ 或 &amp;&amp;</div>
            </td>
            <td width=10 bgColor=#cccccc height=25>&nbsp;</td>
            <td width=368 bgColor=#cccccc height=25>逻辑与</td>
        </tr>
        <tr>
            <td width=114 bgColor=#f0f0f0 height=25>
            <div align=center>or $or$ 或 ||</div>
            </td>
            <td width=10 bgColor=#eeeeee height=25>&nbsp;</td>
            <td width=368 bgColor=#eeeeee height=25>逻辑或</td>
        </tr>
        <tr>
            <td width=114 bgColor=#eeeeee height=25>
            <div align=center>not() $not$</div>
            </td>
            <td width=10 bgColor=#cccccc height=25>&nbsp;</td>
            <td width=368 bgColor=#cccccc height=25>逻辑非</td>
        </tr>
    </tbody>
</table>
<p>　　表三、关系运算符<br></p>
<table style="FONT-SIZE: 12px" cellSpacing=0 cellPadding=0 width=500 align=center border=0>
    <tbody>
        <tr>
            <td width=114 bgColor=#666666 height=25>&nbsp;<font color=#ffffff>可选方式</font></td>
            <td width=10 bgColor=#000000 height=25>&nbsp;</td>
            <td width=368 bgColor=#000000><font color=#ffffff>描述</font></td>
        </tr>
        <tr>
            <td width=114 bgColor=#eeeeee height=25>
            <div align=center>= 或 $eq$</div>
            </td>
            <td width=10 bgColor=#cccccc height=25>&nbsp;</td>
            <td width=368 bgColor=#cccccc height=25>相等</td>
        </tr>
        <tr>
            <td width=114 bgColor=#f0f0f0 height=25>
            <div align=center>= 或 $ieq$</div>
            </td>
            <td width=10 bgColor=#eeeeee height=25>&nbsp;</td>
            <td width=368 bgColor=#eeeeee height=25>相等（不区分大小写）</td>
        </tr>
        <tr>
            <td width=114 bgColor=#eeeeee height=25>
            <div align=center>!= 或 $ne$</div>
            </td>
            <td width=10 bgColor=#cccccc height=25>&nbsp;</td>
            <td width=368 bgColor=#cccccc height=25>不等</td>
        </tr>
        <tr>
            <td width=114 bgColor=#f0f0f0 height=25>
            <div align=center>$ine$</div>
            </td>
            <td width=10 bgColor=#eeeeee height=25>&nbsp;</td>
            <td width=368 bgColor=#eeeeee height=25>不等（不区分大小写）</td>
        </tr>
        <tr>
            <td width=114 bgColor=#eeeeee height=25>
            <div align=center>&lt; 或 $lt$ </div>
            </td>
            <td width=10 bgColor=#cccccc height=25>&nbsp;</td>
            <td width=368 bgColor=#cccccc height=25>小于</td>
        </tr>
        <tr>
            <td width=114 bgColor=#f0f0f0 height=25>
            <div align=center>$ilt$</div>
            </td>
            <td width=10 bgColor=#eeeeee height=25>&nbsp;</td>
            <td width=368 bgColor=#eeeeee height=25>小于（不区分大小写）</td>
        </tr>
        <tr>
            <td width=114 bgColor=#eeeeee height=25>
            <div align=center>&lt;= 或 $le$</div>
            </td>
            <td width=10 bgColor=#cccccc height=25>&nbsp;</td>
            <td width=368 bgColor=#cccccc height=25>小于等于</td>
        </tr>
        <tr>
            <td width=114 bgColor=#f0f0f0 height=25>
            <div align=center>$ile$</div>
            </td>
            <td width=10 bgColor=#eeeeee height=25>&nbsp;</td>
            <td width=368 bgColor=#eeeeee height=25>小于等于（不区分大小写）</td>
        </tr>
        <tr>
            <td width=114 bgColor=#eeeeee height=25>
            <div align=center>&gt; 或 $gt$ </div>
            </td>
            <td width=10 bgColor=#cccccc height=25>&nbsp;</td>
            <td width=368 bgColor=#cccccc height=25>大于</td>
        </tr>
        <tr>
            <td width=114 bgColor=#f0f0f0 height=25>
            <div align=center>$igt$</div>
            </td>
            <td width=10 bgColor=#eeeeee height=25>&nbsp;</td>
            <td width=368 bgColor=#eeeeee height=25>大于（不区分大小写）</td>
        </tr>
        <tr>
            <td width=114 bgColor=#eeeeee height=25>
            <div align=center>&gt;= 或 $ge$</div>
            </td>
            <td width=10 bgColor=#cccccc height=25>&nbsp;</td>
            <td width=368 bgColor=#cccccc height=25>大于等于</td>
        </tr>
        <tr>
            <td width=114 bgColor=#f0f0f0 height=25>
            <div align=center>$ige$</div>
            </td>
            <td width=10 bgColor=#eeeeee height=25>&nbsp;</td>
            <td width=368 bgColor=#eeeeee height=25>大于等于（不区分大小写） </td>
        </tr>
        <tr>
            <td width=114 bgColor=#eeeeee height=25>
            <div align=center>$all$ </div>
            </td>
            <td width=10 bgColor=#cccccc height=25>&nbsp;</td>
            <td width=368 bgColor=#cccccc height=25>集合运算符，如果集合中所有项目均满足条件则返回"真" </td>
        </tr>
        <tr>
            <td width=114 bgColor=#f0f0f0 height=25>
            <div align=center>$any$</div>
            </td>
            <td width=10 bgColor=#eeeeee height=25>&nbsp;</td>
            <td width=368 bgColor=#eeeeee height=25>集合运算符，如果集合中任意项目满足条件则返回"真" </td>
        </tr>
        <tr>
            <td width=114 bgColor=#eeeeee height=25>
            <div align=center>|</div>
            </td>
            <td width=10 bgColor=#cccccc height=25>&nbsp;</td>
            <td width=368 bgColor=#cccccc height=25>集合运算符，返回两个集合的联合</td>
        </tr>
    </tbody>
</table>
<p>　　示例一：</p>
<p>　　从个人简历中寻找具有具有"WEB开发"技能的人的姓名与E-Mail。假设文档结构如下所示：</p>
<p>&lt;document&gt;<br>&lt;resume&gt;<br>&lt;name&gt;name&lt;/name&gt;<br>&lt;sex&gt;sex&lt;/sex&gt;<br>&lt;birthday&gt;birthday&lt;/birthday&gt;<br>&lt;skill&gt;skill1&lt;/skill&gt;<br>&lt;skill&gt;skill2&lt;/skill2&gt;<br>&#8230;<br>&lt;skill&gt;skilln&lt;/skill&gt;<br>&lt;/resume&gt;<br>&lt;resume&gt;<br>&#8230;<br>&lt;/resume&gt;<br>&#8230;<br>&lt;/document&gt;</p>
<p>　　为从以上结构的个人简历中寻找出所有具有WEB开发"技能的人的姓名与E-Mail的XSL文档结构如下：</p>
<p>&lt;TABLE border="1" cellspacing="0"&gt;<br>&lt;TH&gt;姓名&lt;/TH&gt;&lt;TH&gt;E-Mail&lt;/TH&gt;<br>&lt;xsl:for-each select="resume [$any$skill="WEB开发"]"&gt;<br>&lt;TR&gt;&lt;TD&gt;&lt;xsl:value-of select="name"/&gt;&lt;/TD&gt;<br>&lt;TD&gt;&lt;xsl:value-of select="E-Mail"/&gt;&lt;/TD&gt;<br>&lt;/TR&gt;<br>&lt;/xsl:for-each&gt;<br>&lt;/TABLE&gt;</p>
<p>　　说明：</p>
<p>　　1.[ ] ── 表示选择条件，只有满足条件的个人简历才被显示。</p>
<p>　　2.$any$ ── 由于每个人有多种技能，故加$any$作为前缀，以使每个人所有技能都能被比较。</p>
<p>　　3.skill='WEB开发' ── 筛选条件。</p>
<p>　　示例二、</p>
<p>　　仍上面的XML文档为例，如果欲选择1977/1/1之前出生的人的姓名、技能与E-Mail，相应的XSL文档结构如下（假定生日格式为yyyy/mm/dd）：</p>
<p>&lt;TABLE border="1" cellspacing="0"&gt;<br>&lt;TH&gt;姓名&lt;/TH&gt;&lt;TH&gt;技能&lt;/TH&gt;&lt;TH&gt;E-Mail&lt;/TH&gt;<br>&lt;xsl:for-each select="resume[birthday$lt$"1977/1/1"]"&gt;<br>&lt;TR&gt;<br>&lt;TD&gt;&lt;xsl:value-of select="name"/&gt;&lt;/TD&gt;<br>&lt;TD&gt;<br>&lt;xsl:value-of select="skill[0]"/&gt;<br>&lt;xsl:for-each select="skill[index()&gt;0]"&gt;、<br>&lt;xsl:value-of select="."/&gt;<br>&lt;/xsl:for-each&gt;<br>&lt;/TD&gt;<br>&lt;TD&gt;&lt;xsl:value-of select="E-Mail"/&gt;&lt;/TD&gt;<br>&lt;/TR&gt;<br>&lt;/xsl:for-each&gt;<br>&lt;/TABLE&gt;</p>
<p>　　说明：</p>
<p>　　1.birthday $lt$ '1977/1/1' ── 搜索条件，在此处使用"&lt; "会错误，故使用"$lt$"表示小于。</p>
<p>　　2.skill [0] ── 表示选择skill的第一项。</p>
<p>　　3.skill [index()&gt;0] ── 表示选择skill的第二项以后（包括第二项）的项目。</p>
<p>　　4.xsl:value-of select="." ── 表示选择当前标记的值。</p>
<p>　　相信大家应该注意到，在前面以及本次的例子中出现了一些函数，如index()、formatIndex()、childNumber()，也许大家还不完全明了其中的含义吧？敬请关注下一课。</p>
&nbsp; 
<img src ="http://www.cnitblog.com/stomic/aggbug/30956.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/stomic/" target="_blank">大话人生</a> 2007-07-31 03:13 <a href="http://www.cnitblog.com/stomic/archive/2007/07/31/30956.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>我学XSL（一） </title><link>http://www.cnitblog.com/stomic/archive/2007/07/31/30955.html</link><dc:creator>大话人生</dc:creator><author>大话人生</author><pubDate>Mon, 30 Jul 2007 19:10:00 GMT</pubDate><guid>http://www.cnitblog.com/stomic/archive/2007/07/31/30955.html</guid><wfw:comment>http://www.cnitblog.com/stomic/comments/30955.html</wfw:comment><comments>http://www.cnitblog.com/stomic/archive/2007/07/31/30955.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/stomic/comments/commentRss/30955.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/stomic/services/trackbacks/30955.html</trackback:ping><description><![CDATA[随着Internet的发展，越来越多的信息进入互联网，信息的交换、检索、保存及再利用等迫切的需求使HTML这种最常用的标记语言已越来越捉襟见肘。HTML将数据内容与表现融为一体，可修改性、数据可检索性差，而XML借鉴了HTML与数据库、程序语言的优点，将内容与表现分开，不仅使检索更为方便，更主要的是用户之间数据的交换更加方便，可重用性更强。
<p>　　XML是一种元标记语言，没有许多固定的标记，为WEB开发人员提供了更大的灵活性。当我们使用HTML时，标记只是简单的表示内容的显示形式，而与表示的内容没有任何关联，为文档的进一步处理带来极大的不便。比如要表示个人简历，用HTML的表示方式如下：</p>
<p>&lt;HTML&gt;<br>&lt;BODY&gt;<br>&lt;TABLE border=1 cellspacing=0&gt;<br>&lt;TH&gt;姓名&lt;TD&gt;禹希初&lt;TH&gt;性别&lt;TD&gt;男&lt;TH&gt;生日&lt;TD&gt;1977.5<br>&lt;TR&gt;<br>&lt;TH&gt;技能&lt;TD colspan=5&gt;数据库设计与维护、WEB开发<br>&lt;/TABLE&gt;<br>&lt;/BODY&gt;<br>&lt;/HTML&gt;<br><br>
<table class=pt11 cellSpacing=0 align=center border=1>
    <tbody>
        <tr>
            <th>姓名 </th>
            <td>禹希初 </td>
            <th>性别 </th>
            <td>男 </td>
            <th>生日 </th>
            <td>1977.5 </td>
        </tr>
        <tr>
            <th>技能 </th>
            <td colSpan=5>数据库设计与维护、WEB开发 </td>
        </tr>
    </tbody>
</table>
</p>
<div align=center><br><span class=pt9>上例在浏览器中的样子</span><br><br></div>
<p>　　在这里，我们无法从标记TH、TD得知其内容表示什么，如果用XML，相应的文档（文件名：个人简历.xml）就可写成如下形式：</p>
<p>&lt;?xml version="1.0" encoding="GB2312"?&gt;<br>&lt;resume&gt;<br>&lt;name&gt;禹希初&lt;/name&gt;<br>&lt;sex&gt;男&lt;/sex&gt;<br>&lt;birthday&gt;1977.5&lt;/birthday&gt;<br>&lt;skill&gt;数据库设计与维护、WEB开发&lt;/skill&gt;<br>&lt;/resume&gt;<br><br></p>
<div align=center><img height=142 alt="" src="http://www.blueidea.com/articleimg/2004/04/1797/0001.gif" width=324 border=0><br><span class=pt9>上例在浏览器中的样子(IE5.0或更新版本)</span><br></div>
<p>说明：</p>
<p>　　version──规定了XML文档的版本，此处只能是1.0；</p>
<p>　　encoding── 此处规定了XML文档的编码类型，此处取值为"GB2312"，也就是"简体中文"。</p>
<p>　　对比两例，使用XML我们可以做到自定义标记，用标记表明内容的含义。这样在Internet上交流资料时，为用计算机处理文档提供了极大的方便，同时我们阅读源文件时也不会被一大堆格式弄得晕头转向。</p>
<p>　　然而，由于XML并没有为标记规定显示方式，如果我们在游览器中查看以上两个文档（建议使用IE5.0或更新版本），我们将看到xml文档并没有以诸如表格的方式来显示。难道我们就不能像HTML一样显示文档吗？回答是否定的。以个人简历为例，需要另建一个格式文件说明各个标记的显示方式，其内容如下（假设文件名为resume.css）：</p>
<p>resume{ display: block;}<br>name{ display: block; font-size:120%;}<br>sex{ display:block; text-indent:2em}<br>birthday{ display:block; text-indent:2em}<br>skill{ display:block; text-indent:2em}</p>
<p>说明：</p>
<p>　　以上均为CSS样式，建议读者参考有关资料熟悉CSS，在以后学习中必须用到，此处由于篇幅关系不作介绍。建立文件resume.css后，在个人简历.xml文件的第一行后添加以下文字：</p>
<p>&lt;?xml-stylesheet type="text/css" href="resume.css"?&gt;</p>
<div align=center><img height=96 alt="" src="http://www.blueidea.com/articleimg/2004/04/1797/0002.gif" width=256 border=0><br><span class=pt9>上例在浏览器中的样子(IE5.0或更新版本)</span><br><br></div>
<p>说明：</p>
<p>　　此处表示引用一个外部CSS样式文件，其中type规定样式类型（可取值为text/css或text/xsl），href规定文件路径。</p>
<p>　　保存文件，再以IE5.0打开文件。怎么样？格式有些不一样吧。好象还不令人满意，文档内容是清晰了，但显示效果比HTML编写的文档就差得多了，XML编写的文档就只能以这种方式显示吗？！</p>
<p>提示：</p>
<p>　　1. 为了更好的理解与掌握XML，建议大家熟悉HTML 4.0与CSS 2.0语法；掌握JavaScript、VBscript中至少一种；编程经验、对数据库理论与SQL的了解均能使大家在学习XML时获益。</p>
<p>　　2. XML文档中标记必须成对出现，如果是空标记也必须有前加"/"的同名标记结束，或使用此种文式&lt;xml_mark/&gt;表示空标记。</p>
<p>　　3. XML以及下面将要介绍的XSL文档，属性值必须用双引号（"）或单引号（&#8217;）括起来。</p>
<p>　　4. XML文档必须是良构的（XSL文档也是XML文档中一种），也就是说标记必须有结束标记、标记可以嵌套但不可交叉，如：</p>
<p>&lt;outer&gt;&lt;inner&gt;&lt;/inner&gt;&lt;inner/&gt;&lt;/outer&gt;</p>
<p>是合法的，而下面的形式</p>
<p>&lt;outer&gt;&lt;inner&gt;&lt;/outer&gt;&lt;/inner&gt;</p>
<p>则是错误的。如果XML文档在浏览时出错，多半是违反了上面提到的规则。<br><br><br>上期我们讲到用CSS（层叠样式表）来格式化XML文档，其效果并不很令人满意。实际上CSS用来格式化HTML标记比较合适些，只是因为它简单才在上例中采用。<br><br>　　XML在更多的时候只是一种数据文件，怎样将它变为我们日常所看到的HTML格式那样的文件呢？如果我们将XML文件比作结构化的原料的话，那么XSL就好像"筛子"与"模子"，筛子选取自己需要的原料，这些原料再通过模子形成最终的产品：HTML。<br><br>　　这个模子大致是这样：我们先设计好表现的页面，再将其中需要从XML中获取数据来填充内容的部分"挖掉"，然后用XSL语句从XML中筛出相关的数据来填充。一言以譬之：这XSL实际上就是HTML的一个"壳子"，XML数据利用这个"壳"来生成"传统"的HTML。<br><br>　　XML在展开时是一个树形结构，我们将树形结构中自定义标记称为节点，节点之间存在父子、兄弟关系，我们要访问其中的结点从根结点就要以"／"来层层进入。<br><br>　　在XSL这个壳中，我们要从原料库XML里提取相关的数据，就要用到XSL提供的模式化查询语言。所谓模式化查询语言，就是通过相关的模式匹配规则表达式从XML里提取数据的特定语句，即我们上面所说的"筛子"。</p>
<p>　　参考微软的"XSL开发者指南"，我们大致可将模式语言分为三种：</p>
<p>　　选择模式：<br><br>&lt;xsl:for-each&gt;、&lt;xsl:value-of&gt;和 &lt;xsl:apply-templates&gt;</p>
<p>　　测试模式：<br><br>&lt;xsl:if&gt; 和&lt;xsl:when&gt;</p>
<p>　　匹配模式：<br><br>&lt;xsl:template&gt;<br><br>　　我们现在就分别对之进行介绍。<br><br>　　一、 选择模式<br><br>　　选择模式语句将数据从XML中提取出来，是一种简单获得数据的方法，这几个标记都有一个select属性，选取XML中特定的结点名的数据。<br><br>　　<strong>1、&lt;xsl:for-each&gt;</strong><br><br>　　如在XML中有这样的数据:<br><br>&lt;author&gt;<br>&lt;name&gt;小禹&lt;/name&gt;<br>&lt;name&gt;春华&lt;/name&gt;<br>&lt;name&gt;秋实&lt;/name&gt;<br>&lt;/author&gt;<br><br>　　我们要读取这三个作者名字，是一个一个地按"author/name"方法来读取吗，可有多个这样的name呀？如果有一种程序性的语句来循环读取有多好啊！<br><br>　　想得很对，XSL提供了这样的具有程序语言性质的语句：&lt;xsl:for-each&gt;<br><br>　　用它读取这三个作者名字的方法如下:<br><br>&lt;xsl:for-each select="author/name"&gt;<br>&#8230;&#8230;<br>&lt;/xsl:for-each&gt;<br><br>　　select，顾名思义，选取，它可以选定XML中特定唯一的标记，也可以选择某一类相同的标记，我们称之为结点集。<br><br>　　语法：<br><br>&lt;xsl:for-each select="pattern" order-by="sort-criteria-list"&gt;<br><br>　　属性：<br><br>　　1.select<br><br>　　根据XSL样式查询考察上下文以决定哪类结点集（满足select条件）使用此样式描述。作为一种简化的表示就是，如果你想对文档中的某一种标记的内容的显示方式进行格式化，就可以将让select等于此元素的标记名。例如欲对标记xml_mark进行格式化，即可用如下方式表示：<br><br>&lt;xsl:for-each select="xml_mark"&gt;<br>&lt;!--样式定义--&gt;<br>&lt;/xsl:for-each&gt;<br><br>　　2.order-by<br><br>　　以分号（;）分隔、作为排序标准的列表。在列表元素前添加加号（+）表示按此标记的内容以升序排序，添加减号（-）表示逆序排序。作为一种简化的表示就是，排序标准列表就是由select规定的标记的子标记的序列，每个标记之间以（;）分隔。</p>
<p>　　<strong>2、&lt;xsl:value-of&gt;</strong><br><br>　　&lt;xsl:for-each&gt;模式只是选取节点，并没有取出节点的值，好比猴子只是爬到了树的某个枝干上，那么就用&lt; xsl:value-of &gt;来摘"胜利果实"吧！<br><br>　　语法：<br><br>&lt;xsl:value-of select="pattern"&gt;提取节点的值<br><br>　　属性：<br><br>　　select用来与当前上下文匹配的XSL式样。简单的讲，如果要在XSL文档某处插入某个XML标记（假定是xml_mark标记）的内容，可用如下方式表示：<br><br>&lt;xsl:value-of select="xml_mark"&gt;&lt;/xsl:value-of&gt;<br><br>　　或<br><br>&lt;xsl:value-of select="xml_mark"/&gt;<br><br>示例：<br><br>　　此处仍以上期的个人简历的作为例子，我们需要对文件（个人简历.xml）作一定修改，确切的说是将其中的第二行：<br><br>&lt;?xml-stylesheet type="text/css" href="resume.css"?&gt;<br><br>　　修改为：<br><br>&lt;?xml-stylesheet type="text/xsl" href="resume.xsl"?&gt;<br><br>　　然后建立一个新文件：resume.xsl，其内容如下：<br><br>&lt;?xml version="1.0" encoding="GB2312"?&gt;<br>&lt;HTML xmlns:xsl="http://www.w3.org/TR/WD-xsl"&gt;<br>&lt;HEAD&gt;<br>&lt;TITLE&gt;个人简历&lt;/TITLE&gt;<br>&lt;/HEAD&gt;&lt;BODY&gt; <br>&lt;xsl:for-each select="resume"&gt;<br>&lt;P/&gt;<br>&lt;TABLE border="1" cellspacing="0"&gt;<br>&lt;CAPTION style="font-size: 150%; font-weight: bold"&gt;<br>个人简历<br>&lt;/CAPTION&gt;<br>&lt;TR&gt;<br>&lt;TH&gt;姓名&lt;/TH&gt;&lt;TD&gt;&lt;xsl:value-of select="name"/&gt;&lt;/TD&gt;<br>&lt;TH&gt;性别&lt;/TH&gt;&lt;TD&gt;&lt;xsl:value-of select="sex"/&gt;&lt;/TD&gt;<br>&lt;TH&gt;生日&lt;/TH&gt;&lt;TD&gt;&lt;xsl:value-of select="birthday"/&gt;&lt;/TD&gt;<br>&lt;/TR&gt;<br>&lt;TR&gt;<br>&lt;TH&gt;技能&lt;/TH&gt;&lt;TD colspan="5"&gt;&lt;xsl:value-of select="skill"/&gt;&lt;/TD&gt;<br>&lt;/TR&gt;<br>&lt;/TABLE&gt;<br>&lt;/xsl:for-each&gt;<br>&lt;/BODY&gt;<br>&lt;/HTML&gt;<br><br></p>
<div align=center><img height=98 alt="" src="http://www.blueidea.com/articleimg/2004/04/1797/0003.gif" width=270 border=0><br><span class=pt9>上例在浏览器中的样子(IE5.0或更新版本)</span><br><br></div>
<p>　　完成这些以后再来让我们看一下辛勤劳动的成果，怎么样？效果不错吧。更酷还在后头呢。现在我们对文件（个人简历.xml）作进一步的修改：<br><br>　　1.在标记&lt;resume&gt;前添加一个新标记&lt;document&gt;；<br><br>　　2.将标记对&lt;resume&gt;&lt;/resume&gt;之间的内容（包括这一对标记）复制并粘贴在其后，并在最后用&lt;document&gt;结束。<br><br>　　3.以Notepad.exe打开文件resume.xsl，在标记&lt;HTML&gt;之后添加文字：&lt;xsl:for-each select="document"&gt;；在标记&lt;/HTML&gt;之前添加文字：&lt;/xsl:for-each&gt;，保存文件。<br><br>　　4.在浏览器中打开文件（个人简历.xml）。看到了什么？两份个人简历！<br><br></p>
<div align=center><img height=98 alt="" src="http://www.blueidea.com/articleimg/2004/04/1797/0003.gif" width=270 border=0><br><img height=98 alt="" src="http://www.blueidea.com/articleimg/2004/04/1797/0003.gif" width=270 border=0><br><span class=pt9>上例在浏览器中的样子(IE5.0或更新版本)</span><br><br></div>
<p><br>　　就这样，利用XML我们可以编写内容与样式完成分离的文档！当然，XSL文件比一般的HTML文件要复杂一些，然而一旦完成则可用于格式化所有同类的XML文档。 </p>
<img src ="http://www.cnitblog.com/stomic/aggbug/30955.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/stomic/" target="_blank">大话人生</a> 2007-07-31 03:10 <a href="http://www.cnitblog.com/stomic/archive/2007/07/31/30955.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>跟我学xml和XSL</title><link>http://www.cnitblog.com/stomic/archive/2007/07/31/30954.html</link><dc:creator>大话人生</dc:creator><author>大话人生</author><pubDate>Mon, 30 Jul 2007 19:09:00 GMT</pubDate><guid>http://www.cnitblog.com/stomic/archive/2007/07/31/30954.html</guid><wfw:comment>http://www.cnitblog.com/stomic/comments/30954.html</wfw:comment><comments>http://www.cnitblog.com/stomic/archive/2007/07/31/30954.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/stomic/comments/commentRss/30954.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/stomic/services/trackbacks/30954.html</trackback:ping><description><![CDATA[第一个XML文档<br><br>　　随着Internet的发展，越来越多的信息进入互联网，信息的交换、检索、保存及再利用等迫切的需求使HTML这种最常用的标记语言已越来越捉襟见肘。HTML将数据内容与表现融为一体，可修改性、数据可检索性差，而XML借鉴了HTML与数据库、程序语言的优点，将内容与表现分开，不仅使检索更为方便，更主要的是用户之间数据的交换更加方便，可重用性更强。<br><br>　　XML是一种元标记语言，没有许多固定的标记，为WEB开发人员提供了更大的灵活性。当我们使用HTML时，标记只是简单的表示内容的显示形式，而与表示的内容没有任何关联，为文档的进一步处理带来极大的不便。比如要表示个人简历，用HTML的表示方式如下：&nbsp;<br><br>&lt;&nbsp;HTML&nbsp;&gt;<br><br>&lt;&nbsp;BODY&nbsp;&gt;<br><br>&lt;&nbsp;TABLE&nbsp;border=1&nbsp;cellspacing=0&nbsp;&gt;<br><br>&lt;&nbsp;TH&nbsp;&gt;姓名&lt;&nbsp;TD&nbsp;&gt;禹希初&lt;&nbsp;TH&nbsp;&gt;性别&lt;&nbsp;TD&nbsp;&gt;男&lt;&nbsp;TH&nbsp;&gt;生日&lt;&nbsp;TD&nbsp;&gt;1977.5<br><br>&lt;&nbsp;TR&nbsp;&gt;<br><br>&lt;&nbsp;TH&nbsp;&gt;技能&lt;&nbsp;TD&nbsp;colspan=5&nbsp;&gt;数据库设计与维护、WEB开发<br><br>&lt;&nbsp;/TABLE&nbsp;&gt;<br><br>&lt;&nbsp;/BODY&nbsp;&gt;<br><br>&lt;&nbsp;/HTML&nbsp;&gt;<br><br>　　在这里，我们无法从标记TH、TD得知其内容表示什么，如果用XML，相应的文档（文件名：个人简历.xml）就可写成如下形式：&nbsp;<br><br>&lt;&nbsp;?xml&nbsp;version="1.0"&nbsp;encoding="GB2312"?&nbsp;&gt;<br><br>&lt;&nbsp;resume&nbsp;&gt;<br><br>&lt;&nbsp;name&nbsp;&gt;禹希初&lt;&nbsp;/name&nbsp;&gt;<br><br>&lt;&nbsp;sex&nbsp;&gt;男&lt;&nbsp;/sex&nbsp;&gt;<br><br>&lt;&nbsp;birthday&nbsp;&gt;1977.5&lt;&nbsp;/birthday&nbsp;&gt;<br><br>&lt;&nbsp;skill&nbsp;&gt;数据库设计与维护、WEB开发&lt;&nbsp;/skill&nbsp;&gt;<br><br>&lt;&nbsp;/resume&nbsp;&gt;<br><br>说明：<br><br>　　version──规定了XML文档的版本，此处只能是1.0；<br><br>　　encoding──&nbsp;此处规定了XML文档的编码类型，此处取值为&#8220;GB2312&#8221;，也就是&#8220;简体中文&#8221;。<br><br>　　对比两例，使用XML我们可以做到自定义标记，用标记表明内容的含义。这样在Internet上交流资料时，为用计算机处理文档提供了极大的方便，同时我们阅读源文件时也不会被一大堆格式弄得晕头转向。<br><br>　　然而，由于XML并没有为标记规定显示方式，如果我们在游览器中查看以上两个文档（建议使用IE5.0或更新版本），我们将看到xml文档并没有以诸如表格的方式来显示。难道我们就不能像HTML一样显示文档吗？回答是否定的。以个人简历为例，需要另建一个格式文件说明各个标记的显示方式，其内容如下（假设文件名为resume.css）：&nbsp;<br><br>resume{&nbsp;display:&nbsp;block;}<br><br>name{&nbsp;display:&nbsp;block;&nbsp;font-size:120%;}<br><br>sex{&nbsp;display:block;&nbsp;text-indent:2em}<br><br>birthday{&nbsp;display:block;&nbsp;text-indent:2em}<br><br>skill{&nbsp;display:block;&nbsp;text-indent:2em}<br><br>说明：<br><br>　　以上均为CSS样式，建议读者参考有关资料熟悉CSS，在以后学习中必须用到，此处由于篇幅关系不作介绍。建立文件resume.css后，在个人简历.xml文件的第一行后添加以下文字：&nbsp;<br><br>&lt;&nbsp;?xml:stylesheet&nbsp;type="text/css"&nbsp;href="resume.css"?&nbsp;&gt;<br><br>说明：<br><br>　　此处表示引用一个外部CSS样式文件，其中type规定样式类型（可取值为text/css或text/xsl），href规定文件路径。<br><br>　　保存文件，再以IE5.0打开文件。怎么样？格式有些不一样吧。好象还不令人满意，文档内容是清晰了，但显示效果比HTML编写的文档就差得多了，XML编写的文档就只能以这种方式显示吗？！<br><br>提示：<br><br>　　1.&nbsp;为了更好的理解与掌握XML，建议大家熟悉HTML&nbsp;4.0与CSS&nbsp;2.0语法；掌握JavaScript、VBscript中至少一种；编程经验、对数据库理论与SQL的了解均能使大家在学习XML时获益。<br><br>　　2.&nbsp;XML文档中标记必须成对出现，如果是空标记也必须有前加&#8220;/&#8221;的同名标记结束，或使用此种文式&lt;&nbsp;xml_mark/&nbsp;&gt;表示空标记。<br><br>　　3.&nbsp;XML以及下周将要介绍的XSL文档，属性值必须用双引号（"）或单引号（'）括起来。<br><br>　　4.&nbsp;XML文档必须是好结构的（XSL文档也是XML文档中一种），也就是说标记必须有结束标记、标记可以嵌套但不可交叉，如&nbsp;<br><br>&lt;&nbsp;outer&nbsp;&gt;&lt;&nbsp;inner&nbsp;&gt;&lt;&nbsp;/inner&nbsp;&gt;&lt;&nbsp;inner/&nbsp;&gt;&lt;&nbsp;/outer&nbsp;&gt;<br><br>是合法的，而下面的形式&nbsp;<br><br>&lt;&nbsp;outer&nbsp;&gt;&lt;&nbsp;inner&nbsp;&gt;&lt;&nbsp;/outer&nbsp;&gt;&lt;&nbsp;/inner&nbsp;&gt;<br><br>则是错误的。如果XML文档在浏览时出错，多半是违反了上面提到的规则。<br><br>跟我学XSL（二）（返回标题）<br><br>2000-05-04&#183;&nbsp;禹希初&#183;CPCW<br><br>XSL入门<br><br>　　上期我们讲到用CSS（层叠样式表）来格式化XML文档，其效果并不很令人满意。实际上CSS用来格式化HTML标记比较合适些，只是因为它简单才在上例中采用。<br><br>　　XML在更多的时候只是一种数据文件，怎样将它变为我们日常所看到的HTML格式那样的文件呢？如果我们将XML文件比作结构化的原料的话，那么XSL就好比&#8220;筛子&#8220;与&#8220;模子&#8220;，筛子选取自己需要的原料，这些原料再通过模子形成最终的产品：HTML。<br><br>　　这个模子大致是这样：我们先设计好表现的页面，再将其中需要从XML中获取数据来填充内容的部分&#8220;挖掉&#8220;，然后用XSL语句从XML中筛出相关的数据来填充。一言以譬之：这XSL实际上就是HTML的一个&#8220;壳子&#8220;，XML数据利用这个&#8220;壳&#8220;来生成&#8220;传统&#8220;的HTML。<br><br>　　XML在展开时是一个树形结构，我们将树形结构中自定义标记称为节点，节点之间存在父子、兄弟关系，我们要访问其中的结点从根结点就要以&#8221;／&#8221;来层层进入。<br><br>　　在XSL这个壳中，我们要从原料库？？XML里提取相关的数据，就要用到XSL提供的模式化查询语言。所谓模式化查询语言，就是通过相关的模式匹配规则表达式从XML里提取数据的特定语句，即我们上所说的&#8220;筛子&#8220;。<br><br>参考微软的&#8221;XSL开发者指南&#8221;，我们大致可将模式语言分为三种：&nbsp;<br><br>选择模式&nbsp;<br><br>&lt;&nbsp;xsl:for-each&nbsp;&gt;、&lt;&nbsp;xsl:value-of&nbsp;&gt;,和&nbsp;&lt;&nbsp;xsl:apply-templates&nbsp;&gt;<br><br>测试模式&nbsp;<br><br>&lt;&nbsp;xsl:if&nbsp;&gt;&nbsp;和&lt;&nbsp;xsl:when&nbsp;&gt;<br><br>匹配模式&nbsp;<br><br>&lt;&nbsp;xsl:template&nbsp;&gt;&nbsp;<br><br>我们现在就分别对之进行介绍。<br><br>一、&nbsp;选择模式<br><br>　　选择模式语句将数据从XML中提取出来，是一种简单获得数据的方法，这几个标记都有一个select属性，选取XML中特定的结点名的数据。&nbsp;<br><br>1、&lt;&nbsp;xsl:for-each&nbsp;&gt;<br><br>如在XML中有这样的数据:<br><br>&lt;&nbsp;author&nbsp;&gt;<br><br>&lt;&nbsp;name&nbsp;&gt;小禹&lt;&nbsp;/name&nbsp;&gt;<br><br>&lt;&nbsp;name&nbsp;&gt;春华&lt;&nbsp;/name&nbsp;&gt;<br><br>&lt;&nbsp;name&nbsp;&gt;秋实&lt;&nbsp;/name&nbsp;&gt;<br><br>&lt;&nbsp;/author&nbsp;&gt;<br><br>　　我们要读取这三个作者名字，是一个一个地按&#8221;author/name&#8221;方法来读取吗，可有多个这样的name呀？如果有一种程序性的语句来循环读取有多好啊！<br><br>　　想得很对，XSL提供了这样的具有程序语言性质的语句&lt;&nbsp;XSL:for-each&nbsp;&gt;<br><br>　　用它读取这三个作者名字的方法如下:<br><br>&lt;&nbsp;xsl:for-each&nbsp;select=&#8221;author/name&#8221;&nbsp;&gt;<br><br>&#8230;&#8230;.<br><br>&lt;&nbsp;./xsl:for-each&nbsp;&gt;<br><br>select，顾名思义：选取，它可以选定XML中特定唯一的标记，也可以选择某一类相同的标记，我们称之为结点集。&nbsp;<br><br>语法：&nbsp;<br><br>&lt;&nbsp;xsl:for-each&nbsp;select="pattern"&nbsp;order-by="sort-criteria-list"&gt;<br><br>属性：&nbsp;<br><br>1.&nbsp;select<br><br>　　根据XSL样式查询考察上下文以决定哪类结点集（满足select条件）使用此样式描述。作为一种简化的表示就是，如果你想对文档中的某一种标记的内容的显示方式进行格式化，就可以将让select等于此元素的标记名。例如欲对标记xml_mark进行格式化，即可用如下方式表示：&nbsp;<br><br>&lt;&nbsp;xsl:for-each&nbsp;select="xml_mark"&nbsp;&gt;<br><br>&lt;&nbsp;!--样式定义--&nbsp;&gt;<br><br>&lt;&nbsp;/xsl:for-each&nbsp;&gt;<br><br>2.&nbsp;order-by<br><br>　　以分号（;）分隔、作为排序标准的列表。在列表元素前添加加号（+）表示按此标记的内容以升序排序，添加减号（-）表示逆序排序。作为一种简化的表示就是，排序标准列表就是由select规定的标记的子标记的序列，每个标记之间以（;）分隔。&nbsp;<br><br>2、&lt;&nbsp;xsl:value-of&nbsp;&gt;<br><br>&lt;&nbsp;xsl:for-each&nbsp;&gt;模式只是选取节点，并没有取出节点的值，好比猴子只是爬到了树的某个枝干上，那么就用&lt;&nbsp;xsl:value-of&nbsp;&gt;来摘&#8220;胜利果实&#8220;吧！&nbsp;<br><br>语法：&nbsp;<br><br>&lt;&nbsp;xsl:value-of&nbsp;select="pattern"&nbsp;&gt;提取节点的值&nbsp;<br><br>属性：&nbsp;<br><br>select用来与当前上下文匹配的XSL式样。简单的讲，如果要在XSL文档某处插入某个XML标记（假定是xml_mark标记）的内容，可用如下方式表示：&nbsp;<br><br>&lt;&nbsp;xsl:value-of&nbsp;select="xml_mark"&nbsp;&gt;&lt;&nbsp;/xsl:value-of&nbsp;&gt;<br><br>或&nbsp;<br><br>&lt;&nbsp;xsl:value-of&nbsp;select="xml_mark"/&nbsp;&gt;<br><br>示例：<br><br>　　此处仍以上期的个人简历的作为例子，我们需要对文件（个人简历.xml）作一定修改，确切的说是将其中的第二行&nbsp;<br><br>&lt;&nbsp;?xml:stylesheet&nbsp;type="text/css"&nbsp;href="resume.css"?&nbsp;&gt;<br><br>修改为&nbsp;<br><br>&lt;&nbsp;?xml:stylesheet&nbsp;type="text/xsl"&nbsp;href="resume.xsl"?&nbsp;&gt;<br><br>然后建立一个新文件：resume.xsl，其内容如下：&nbsp;<br><br>&lt;&nbsp;?xml&nbsp;version="1.0"&nbsp;encoding="GB2312"?&nbsp;&gt;<br><br>&lt;&nbsp;HTML&nbsp;xmlns:xsl="<a href="http://www.w3.org/TR/WD-xsl%22" target=_blank href_cetemp='http://www.w3.org/TR/WD-xsl"'><font color=#002c99><u>http://www.w3.org/TR/WD-xsl"</u></font></a> &nbsp;&gt;<br><br>&lt;&nbsp;HEAD&nbsp;&gt;<br><br>&lt;&nbsp;TITLE&nbsp;&gt;个人简历&lt;&nbsp;/TITLE&nbsp;&gt;<br><br>&lt;&nbsp;/HEAD&nbsp;&gt;&lt;&nbsp;BODY&nbsp;&gt;&nbsp;<br><br>&lt;&nbsp;xsl:for-each&nbsp;select="resume"&nbsp;&gt;<br><br>&lt;&nbsp;P/&nbsp;&gt;<br><br>&lt;&nbsp;TABLE&nbsp;border="1"&nbsp;cellspacing="0"&nbsp;&gt;<br><br>&lt;&nbsp;CAPTION&nbsp;style="font-size:&nbsp;150%;&nbsp;font-weight:&nbsp;bold"&nbsp;&gt;<br><br>个人简历&nbsp;<br><br>&lt;&nbsp;/CAPTION&nbsp;&gt;<br><br>&lt;&nbsp;TR&nbsp;&gt;<br><br>&lt;&nbsp;TH&nbsp;&gt;姓名&lt;&nbsp;/TH&nbsp;&gt;&lt;&nbsp;TD&nbsp;&gt;&lt;&nbsp;xsl:value-of&nbsp;select="name"/&nbsp;&gt;&lt;&nbsp;/TD&nbsp;&gt;<br><br>&lt;&nbsp;TH&nbsp;&gt;性别&lt;&nbsp;/TH&nbsp;&gt;&lt;&nbsp;TD&nbsp;&gt;&lt;&nbsp;xsl:value-of&nbsp;select="sex"/&nbsp;&gt;&lt;&nbsp;/TD&nbsp;&gt;<br><br>&lt;&nbsp;TH&nbsp;&gt;生日&lt;&nbsp;/TH&nbsp;&gt;&lt;&nbsp;TD&nbsp;&gt;&lt;&nbsp;xsl:value-of&nbsp;select="birthday"/&nbsp;&gt;&lt;&nbsp;/TD&nbsp;&gt;<br><br>&lt;&nbsp;/TR&nbsp;&gt;<br><br>&lt;&nbsp;TR&nbsp;&gt;<br><br>&lt;&nbsp;TH&nbsp;&gt;技能&lt;&nbsp;/TH&nbsp;&gt;&lt;&nbsp;TD&nbsp;colspan="5"&nbsp;&gt;&lt;&nbsp;xsl:value-of&nbsp;select="skill"/&nbsp;&gt;&lt;&nbsp;/TD&nbsp;&gt;<br><br>&lt;&nbsp;/TR&nbsp;&gt;<br><br>&lt;&nbsp;/TABLE&nbsp;&gt;<br><br>&lt;&nbsp;/xsl:for-each&nbsp;&gt;<br><br>&lt;&nbsp;/BODY&nbsp;&gt;<br><br>&lt;&nbsp;/HTML&nbsp;&gt;<br><br>　　完成这些以后再来让我们看一下辛勤劳动的成果，怎么样？效果不错吧。更酷还在后头呢。现在我们对文件（个人简历.xml）作进一步的修改：&nbsp;<br><br>1.&nbsp;在标记&lt;&nbsp;resume&nbsp;&gt;前添加一个新标记&lt;&nbsp;document&nbsp;&gt;；&nbsp;<br><br>2.&nbsp;将标记对&lt;&nbsp;resume&nbsp;&gt;&lt;&nbsp;/resume&nbsp;&gt;之间的内容（包括这一对标记）复制并粘贴在其后，并在最后用&lt;&nbsp;document&nbsp;&gt;结束。&nbsp;<br><br>3.&nbsp;以Notepad.exe打开文件resume.xsl，在标记&lt;&nbsp;HTML&nbsp;&gt;之后添加文字：&lt;&nbsp;xsl:for-each&nbsp;select="document"&nbsp;&gt;；在标记&lt;&nbsp;/HTML&nbsp;&gt;之前添加文字：&lt;&nbsp;/xsl:for-each&nbsp;&gt;，保存文件。<br><br>4.&nbsp;在浏览器中打开文件（个人简历.xml）。看到了什么？两份个人简历！<br><br>　　就这样，利用XML我们可以编写内容与样式完成分离的文档！当然，XSL文件比一般的HTML文件要复杂一些，然而一旦完成则可用于格式化所有同类的XML文档。<br><br>注：如果拷贝代码，请将空格删除&nbsp;<br><br>跟我学XSL（三）&nbsp;&nbsp;（返回标题）&nbsp;<br><br>2000-05-05&#183;&nbsp;禹希初&#183;CPCW<br><br>XSL模板与匹配模式<br><br>　　经过前几日的学习，我们学习了XHTML文档的编写和以及三个XSL元素，已能编写相当灵活的XSL文档，今天将学习的是XSL模板的编写。我们都知道，短的文档、程序十分好读，但当规模增大后，其复杂性也以更快的速度增加。<br><br>　　前面我们学了&lt;&nbsp;xsl:for-each&nbsp;&gt;、&lt;&nbsp;xsl:value-of&nbsp;&gt;等，可以用它们对XML数据实现简单的格式化输出，但如果遇到比较复杂的XML格式输出，将XSL按照要求依次写下来的话，一是设计困难，可扩展性差，不利于人员之间的分工协作；另则，可修改性很差，可能会出现牵一发而动全军的情况，不利于维护。程序中模块化设计逐步细化的方法在这里得到了应用！&nbsp;<br><br>　　XSL模板将XSL的设计细化成一个个模板（块），最后再将这些模板（块）组合成一个完整的XSL；好比船与集装箱，我们不是将所有的货物一件件地堆起来，而是装在各自的集装箱中，然后再在船上将这些集装箱堆放起来。这种方法可以使你先从整体上考虑整个XSL的设计，然后将一些表现形式细化成不同的模块，再具体设计这些模块，最后将它们整合在一起，这样，将宏观与微观结合起来，符合人们条理化、规范化要求。<br><br>装集装箱？？书写模板（块）：&lt;&nbsp;xsl:template&nbsp;&gt;<br><br>&lt;&nbsp;xsl:template&nbsp;&gt;<br><br>语法：&nbsp;<br><br>&lt;&nbsp;xsl:template&nbsp;match="node-context"&nbsp;language="language-name"&nbsp;&gt;<br><br>属性：&nbsp;<br><br>match&nbsp;──&nbsp;确定什么样的情况下执行此模板。作为一种简化的说明，在此处使用标记的名字；其中最上层模板必须将match设为&#8220;/&#8221;<br><br>language&nbsp;──&nbsp;确定在此模板中执行什么脚本语言，其取值与HTML中的SCRIPT标记的LANGUAGE属性的取值相同，缺省值是Jscript<br><br>&lt;&nbsp;xsl:template&nbsp;&gt;用match属性从XML选取满足条件的节点，征对这些特定的节点形成一个特定输出形式的模板。<br><br>吊集装箱上船-？？调用模板（块）：&lt;&nbsp;xsl:apply-templates&nbsp;&gt;<br><br>&lt;&nbsp;xsl:apply-templates&nbsp;&gt;<br><br>语法：&nbsp;<br><br>&lt;&nbsp;xsl:apply-templates&nbsp;select="pattern"&nbsp;order-by="sort-criteria-list"&nbsp;&gt;<br><br>属性：&nbsp;<br><br>select&nbsp;──&nbsp;确定在此上下文环境中应执行什么模板，即选取用&lt;&nbsp;xsl:template&nbsp;&gt;标记建立的模板（块）。&nbsp;<br><br>order-by&nbsp;──&nbsp;以分号（;）分隔的排序标准，通常是子标记的序列<br><br>示例：<br><br>　　以个人简历为例，为便于处理我们希望&#8220;技能&#8221;中每一项都用标记对&lt;&nbsp;skill&nbsp;&gt;&lt;&nbsp;/skill&nbsp;&gt;括起来，有多少项技能就有多少个这种标记对，经过修改后的个人简历XML文档内容如下：&nbsp;<br><br>&lt;&nbsp;?xml&nbsp;version="1.0"&nbsp;encoding="GB2312"?&nbsp;&gt;<br><br>&lt;&nbsp;?xml:stylesheet&nbsp;type="text/xsl"&nbsp;href="resume_template.xsl"?&nbsp;&gt;<br><br>&lt;&nbsp;document&nbsp;&gt;<br><br>&lt;&nbsp;resume&nbsp;&gt;<br><br>&lt;&nbsp;name&nbsp;&gt;禹希初&lt;&nbsp;/name&nbsp;&gt;<br><br>&lt;&nbsp;sex&nbsp;&gt;男&lt;&nbsp;/sex&nbsp;&gt;<br><br>&lt;&nbsp;birthday&nbsp;&gt;1977.5&lt;&nbsp;/birthday&nbsp;&gt;<br><br>&lt;&nbsp;skill&nbsp;&gt;数据库设计与维护&lt;&nbsp;/skill&nbsp;&gt;<br><br>&lt;&nbsp;skill&nbsp;&gt;WEB开发&lt;&nbsp;/skill&nbsp;&gt;<br><br>&lt;&nbsp;/resume&nbsp;&gt;<br><br>&lt;&nbsp;/document&nbsp;&gt;<br><br>　　然后，建立一个新XSL文件resume_template.xsl，采用模板的形式，其内容如下：&nbsp;<br><br>&lt;&nbsp;?xml&nbsp;version="1.0"&nbsp;encoding="GB2312"?&nbsp;&gt;<br><br>&lt;&nbsp;xsl:stylesheet&nbsp;xmlns:xsl="<a href="http://www.w3.org/TR/WD-xsl%22" target=_blank href_cetemp='http://www.w3.org/TR/WD-xsl"'><font color=#002c99><u>http://www.w3.org/TR/WD-xsl"</u></font></a> &nbsp;&gt;<br><br>&lt;&nbsp;!--根模板--&nbsp;&gt;<br><br>&lt;&nbsp;xsl:template&nbsp;match="/"&nbsp;&gt;<br><br>&lt;&nbsp;HTML&nbsp;&gt;&lt;&nbsp;HEAD&nbsp;&gt;&lt;&nbsp;TITLE&nbsp;&gt;个人简历&lt;&nbsp;/TITLE&nbsp;&gt;&lt;&nbsp;/HEAD&nbsp;&gt;<br><br>&lt;&nbsp;BODY&nbsp;&gt;<br><br>&lt;&nbsp;xsl:apply-templates&nbsp;select="document/resume"/&nbsp;&gt;<br><br>&lt;&nbsp;/BODY&nbsp;&gt;<br><br>&lt;&nbsp;/HTML&nbsp;&gt;<br><br>&lt;&nbsp;/xsl:template&nbsp;&gt;<br><br>&lt;&nbsp;!--简历模板--&nbsp;&gt;<br><br>&lt;&nbsp;xsl:template&nbsp;match="resume"&nbsp;&gt;<br><br>&lt;&nbsp;TABLE&nbsp;border="1"&nbsp;cellspacing="0"&nbsp;&gt;<br><br>&lt;&nbsp;CAPTION&nbsp;&gt;个人简历（&nbsp;<br><br>&lt;&nbsp;xsl:eval&nbsp;&gt;formatIndex(childNumber(this),&nbsp;"I")&lt;&nbsp;/xsl:eval&nbsp;&gt;<br><br>）&lt;&nbsp;/CAPTION&nbsp;&gt;<br><br>&lt;&nbsp;xsl:apply-templates&nbsp;select="name"&nbsp;/&nbsp;&gt;<br><br>&lt;&nbsp;xsl:apply-templates&nbsp;select="sex"&nbsp;/&nbsp;&gt;<br><br>&lt;&nbsp;xsl:apply-templates&nbsp;select="birthday"&nbsp;/&nbsp;&gt;<br><br>&lt;&nbsp;TR/&nbsp;&gt;<br><br>&lt;&nbsp;TD&nbsp;&gt;技能&lt;&nbsp;/TD&nbsp;&gt;&lt;&nbsp;TD&nbsp;COLSPAN="5"&nbsp;&gt;<br><br>&lt;&nbsp;TABLE&nbsp;cellspacing="0"&nbsp;&gt;<br><br>&lt;&nbsp;xsl:apply-templates&nbsp;select="skill"/&nbsp;&gt;<br><br>&lt;&nbsp;/TABLE&nbsp;&gt;<br><br>&lt;&nbsp;/TD&nbsp;&gt;<br><br>&lt;&nbsp;/TABLE&nbsp;&gt;<br><br>&lt;&nbsp;BR/&nbsp;&gt;<br><br>&lt;&nbsp;/xsl:template&nbsp;&gt;<br><br>&lt;&nbsp;!--姓名模板--&nbsp;&gt;<br><br>&lt;&nbsp;xsl:template&nbsp;match="name"&nbsp;&gt;&lt;&nbsp;TD&nbsp;&gt;姓名&lt;&nbsp;/TD&nbsp;&gt;<br><br>&lt;&nbsp;TD&nbsp;&gt;&lt;&nbsp;xsl:value-of/&nbsp;&gt;&lt;&nbsp;/TD&nbsp;&gt;<br><br>&lt;&nbsp;/xsl:template&nbsp;&gt;<br><br>&lt;&nbsp;!--性别模板--&nbsp;&gt;<br><br>&lt;&nbsp;xsl:template&nbsp;match="sex"&nbsp;&gt;&lt;&nbsp;TD&nbsp;&gt;性别&lt;&nbsp;/TD&nbsp;&gt;<br><br>&lt;&nbsp;TD&nbsp;&gt;&lt;&nbsp;xsl:value-of/&nbsp;&gt;&lt;&nbsp;/TD&nbsp;&gt;<br><br>&lt;&nbsp;/xsl:template&nbsp;&gt;<br><br>&lt;&nbsp;!--生日模板--&nbsp;&gt;<br><br>&lt;&nbsp;xsl:template&nbsp;match="birthday"&nbsp;&gt;&lt;&nbsp;TD&nbsp;&gt;生日&lt;&nbsp;/TD&nbsp;&gt;<br><br>&lt;&nbsp;TD&nbsp;&gt;&lt;&nbsp;xsl:value-of/&nbsp;&gt;&lt;&nbsp;/TD&nbsp;&gt;<br><br>&lt;&nbsp;/xsl:template&nbsp;&gt;<br><br>&lt;&nbsp;!--技能模板--&nbsp;&gt;<br><br>&lt;&nbsp;xsl:template&nbsp;match="skill"&nbsp;&gt;<br><br>&lt;&nbsp;TR&nbsp;&gt;&lt;&nbsp;TD&nbsp;&gt;&lt;&nbsp;xsl:value-of/&nbsp;&gt;&lt;&nbsp;/TD&nbsp;&gt;&lt;&nbsp;/TR&nbsp;&gt;<br><br>&lt;&nbsp;/xsl:template&nbsp;&gt;<br><br>&lt;&nbsp;/xsl:stylesheet&nbsp;&gt;<br><br>　　保存文件，打开文件（个人简历.xml），效果令人满意吧。其实要做到同样的效果，用前面三周介绍的方法也可做，但你得把它作为一整体考虑。<br><br>　　在上面的XSL文件中，我们将性别、生日、技能等数据项分别用模板来单独写，再用&lt;&nbsp;xsl:apply-template&nbsp;&gt;来调用，这样，即使你日后要对这些模板作相应的修改与扩充也很方便，不致于出现互相干扰、混杂不清的情况。这种从上至下、逐层细化的设计方法，极大地减少工作复杂程度，也大大减少了差错的产生，可以实现多人的协作设计。<br><br>注意：<br><br>　　如果XML文档中不同标记有同名的子标记，在为其编写模板时，应把父标记作为其前缀，格式为（parent_mark/child_mark）。<br><br>　　模板文件必须有一个根模板，其属性match是&#8220;/&#8221;。<br><br>注：如果拷贝源代码，请将空格删除&nbsp;<br><br>跟我学XSL（四）&nbsp;&nbsp;（返回标题）&nbsp;<br><br>2000-05-06&#183;&nbsp;禹希初&#183;CPCW<br><br>测试模式&nbsp;<br><br>　　XML技术的优势之一就在于数据输出的可选择性，即选择需要的数据输出。前面我们所讲到的选择模式语句:&lt;xsl:for-each&gt;、&lt;xsl:value-of&gt;及&lt;xsl:apply-template&gt;只是简单的选取通过&#8221;/&#8221;符号层层到达的节点，如果我们对XML数据不需要全部输出，而只需要其中的满足某条件的部分数据，&#8220;萝卜青菜、各取所需&#8220;，那么条件判断&lt;xsl:if&gt;与多条件判断&lt;xsl:choose&gt;及&lt;xsl:when&gt;则迎合了这种需要，如果你对程序设计熟悉的话，会觉得它们似曾相识。&nbsp;<br><br>XSL中的IF，首先，介绍XSL元素&lt;xsl:if&gt;的语法结构：&nbsp;<br><br>&lt;xsl:if&gt;&nbsp;<br><br>语法：&nbsp;<br><br>&lt;xsl:if&nbsp;expr="script-expression"&nbsp;language="language-name"&nbsp;test="pattern"&gt;&nbsp;<br><br>属性：&nbsp;<br><br>　　expr&nbsp;──脚本语言表达式，计算结果为&#8220;真&#8221;或&#8220;假&#8221;；如果结果为&#8220;真&#8221;，且通过test，则在输出中显示其中内容（可省略此项属性）。&nbsp;<br><br>　　language&nbsp;──expr属性中表达式的脚本语言类型，其取值与HTML标记SCRIPT的LANGUAGE属性的取值相同，缺省为&#8220;JScript&#8221;test&nbsp;──源数据测试条件。&nbsp;<br><br>示例：&nbsp;<br><br>此处以一份报表为例，文件名为report.xml，其内容如下：&nbsp;<br><br>&lt;?xml&nbsp;version="1.0"&nbsp;encoding="GB2312"?&gt;&nbsp;<br><br>&lt;?xml:stylesheet&nbsp;type="text/xsl"&nbsp;href="report.xsl"?&gt;&nbsp;<br><br>&lt;document&gt;&nbsp;<br><br>&lt;report&gt;&nbsp;<br><br>&lt;class&gt;&nbsp;<br><br>甲班&nbsp;<br><br>&lt;/class&gt;&lt;q1&gt;50&lt;/q1&gt;&lt;q2&gt;70&lt;/q2&gt;&nbsp;<br><br>&lt;q3&gt;30&lt;/q3&gt;&lt;q4&gt;10&lt;/q4&gt;&lt;/report&gt;&nbsp;<br><br>&lt;report&gt;&lt;class&gt;&nbsp;<br><br>乙班&nbsp;<br><br>&lt;/class&gt;&lt;q1&gt;20&lt;/q1&gt;&lt;q2&gt;30&lt;/q2&gt;&nbsp;<br><br>&lt;q3&gt;40&lt;/q3&gt;&lt;q4&gt;50&lt;/q4&gt;&lt;/report&gt;&nbsp;<br><br>&lt;report&gt;&lt;class&gt;&nbsp;<br><br>丙班&nbsp;<br><br>&lt;/class&gt;&lt;q1&gt;70&lt;/q1&gt;&lt;q2&gt;40&lt;/q2&gt;&nbsp;<br><br>&lt;q3&gt;20&lt;/q3&gt;&lt;q4&gt;10&lt;/q4&gt;&lt;/report&gt;&nbsp;<br><br>&lt;/document&gt;&nbsp;<br><br>　　我们采用XSL模板结合今天所学的&lt;xsl:if&gt;，为其编写一个XSL文档，要求季度产量小于等于20的用红色表示，文件名为report.xsl，内容如下：&nbsp;<br><br>&lt;?xml&nbsp;version="1.0"&nbsp;encoding="GB2312"?&gt;&nbsp;<br><br>&lt;xsl:stylesheet&nbsp;xmlns:xsl="<a href="http://www.w3.org/TR/WD-xsl%22" target=_blank href_cetemp='http://www.w3.org/TR/WD-xsl"'><font color=#002c99><u>http://www.w3.org/TR/WD-xsl"</u></font></a> &gt;&nbsp;<br><br>&lt;xsl:template&nbsp;match="/"&gt;&nbsp;<br><br>&lt;HTML&gt;&lt;HEAD&gt;&lt;TITLE&gt;1999年生产统计&lt;/TITLE&gt;&lt;/HEAD&gt;&nbsp;<br><br>&lt;BODY&gt;&lt;xsl:apply-templates&nbsp;select="document&nbsp;;"/&gt;&lt;/BODY&gt;&nbsp;<br><br>&lt;/HTML&gt;&nbsp;<br><br>&lt;/xsl:template&gt;&nbsp;<br><br>&lt;xsl:template&nbsp;match="document"&gt;&nbsp;<br><br>&lt;H3&gt;1999年生产统计&lt;/H3&gt;&nbsp;<br><br>&lt;TABLE　border="1"&nbsp;cellspacing="0"&gt;&nbsp;<br><br>&lt;TH&gt;班组&lt;/TH&gt;&lt;TH&gt;&nbsp;<br><br>一季度&nbsp;<br><br>&lt;/TH&gt;&lt;TH&gt;&nbsp;<br><br>二季度&nbsp;<br><br>&lt;/TH&gt;&nbsp;<br><br>&lt;TH&gt;&nbsp;<br><br>三季度&nbsp;<br><br>&lt;/TH&gt;&lt;TH&gt;&nbsp;<br><br>四季度&nbsp;<br><br>&lt;/TH&gt;&nbsp;<br><br>&lt;xsl:apply-templates&nbsp;select="report"/&gt;&nbsp;<br><br>&lt;/TABLE&gt;&nbsp;<br><br>&lt;/xsl:template&gt;&nbsp;<br><br>&lt;xsl:template&nbsp;match="report"&gt;&nbsp;<br><br>&lt;TR&gt;&nbsp;<br><br>&lt;TD&gt;&lt;xsl:value-of&nbsp;select="class"/&gt;&lt;/TD&gt;&nbsp;<br><br>&lt;TD&gt;&lt;xsl:apply-templates&nbsp;select="q1"/&gt;&lt;/TD&gt;&nbsp;<br><br>&lt;TD&gt;&lt;xsl:apply-templates&nbsp;select="q2"/&gt;&lt;/TD&gt;&nbsp;<br><br>&lt;TD&gt;&lt;xsl:apply-templates&nbsp;select="q3"/&gt;&lt;/TD&gt;&nbsp;<br><br>&lt;TD&gt;&lt;xsl:apply-templates&nbsp;select="q4"/&gt;&lt;/TD&gt;&nbsp;<br><br>&lt;/TR&gt;&nbsp;<br><br>&lt;/xsl:template&gt;&nbsp;<br><br>&lt;xsl:template&nbsp;match="q1|q2|q3|q4"&gt;&nbsp;<br><br>&lt;!--此处测试产量，如小于等于20则添加一STYLE属性color，其值为red（红色）--&gt;&nbsp;<br><br>&lt;xsl:if&nbsp;test=".[value()&nbsp;$le$&nbsp;20]"&gt;&nbsp;<br><br>&lt;xsl:attribute&nbsp;name="style"&gt;color:red&lt;/xsl:attribute&gt;&nbsp;<br><br>&lt;/xsl:if&gt;&nbsp;<br><br>&lt;xsl:value-of/&gt;&nbsp;<br><br>&lt;/xsl:template&gt;&nbsp;<br><br>&lt;/xsl:stylesheet&gt;&nbsp;<br><br>说明：&nbsp;<br><br>q1|q2|q3|q4&nbsp;──标记q1、q2、q3、q3均用此模板确定输出&nbsp;<br><br>$le$&nbsp;──是关系运算符中的&#8220;小于等于&#8221;，其它关系有小于（$lt$）、大于（$gt$）、大于等于（$ge$）、等于（$eq$）、不等于（$ne$）等&nbsp;<br><br>.&nbsp;──表示引用当前标记&nbsp;<br><br>[&nbsp;]&nbsp;──表示筛选，只有满足筛选条件的标记才能被选取&nbsp;<br><br>value()&nbsp;──XSL函数，其他常用XSL函数有text()、end()、index()等。&nbsp;<br><br>　　下期，我们将学习XSL的另外三个元素，可对同一数据进行多次测试，根据不同条件产生相应输出。&nbsp;<br><br>跟我学XSL（五）&nbsp;&nbsp;（返回标题）&nbsp;<br><br>2000-05-07&#183;&nbsp;禹希初&#183;CPCW<br><br>XSL中的choose<br><br>　　上期我们学习了XSL元素&lt;&nbsp;xsl:if&nbsp;&gt;，已能通过测试XML数据的值来决定不同的输出形式（不知你尝试过没有，实际上&lt;&nbsp;xsl:for-each&nbsp;&gt;也可部分实现&lt;&nbsp;xsl:if&nbsp;&gt;的功能），但有时，我们希望对同一数据同时测试多个条件，根据不同条件输出相应结果。当然，我们可以用if，假如我们只有if可用的话。幸好我们有一个更好的选择，那就是用&lt;&nbsp;xsl:choose&nbsp;&gt;。下面介绍相关元素的语法：&nbsp;<br><br>&lt;&nbsp;xsl:choose&nbsp;&gt;<br><br>语法：&lt;&nbsp;xsl:choose&nbsp;&gt;<br><br>属性：无，表示一个多选测试的开始&nbsp;<br><br>&lt;&nbsp;xsl:when&nbsp;&gt;<br><br>语法：&nbsp;<br><br>&lt;&nbsp;xsl:when&nbsp;expr="script-expression"&nbsp;language="language-name"&nbsp;test="pattern"&nbsp;&gt;<br><br>属性：&nbsp;<br><br>expr&nbsp;──&nbsp;脚本语言表达式，计算结果为&#8220;真&#8221;或&#8220;假&#8221;；如果结果为&#8220;真&#8221;，且通过test，则在输出中显示其中内容（可省略此项属性）。&nbsp;<br><br>language&nbsp;──&nbsp;expr属性中表达式的脚本语言类型，其取值与HTML标记SCRIPT的LANGUAGE属性的取值相同，缺省为&#8220;Jscript&#8221;。&nbsp;<br><br>test&nbsp;──&nbsp;源数据测试条件。&nbsp;<br><br>&lt;&nbsp;xsl:otherwise&nbsp;&gt;<br><br>语法：&lt;&nbsp;xsl:otherwise&nbsp;&gt;<br><br>属性：无，在一个多选测试中，如果没有不满足&lt;&nbsp;xsl:when&nbsp;&gt;规定的条件，如果在最后有此标记，则输出此标记中的内容。<br><br>示例：<br><br>　　此处以学生成绩单为例，要求按成绩的高低给出优秀（&nbsp;&gt;85）、一般（70~85）、起格（60~69）、不及格（&lt;&nbsp;60），而不是显示分数。其中成绩单的XML文档(文件名：grade.xml)如下：&nbsp;<br><br>&lt;&nbsp;?xml&nbsp;version="1.0"&nbsp;encoding="GB2312"?&nbsp;&gt;<br><br>&lt;&nbsp;?xml:stylesheet&nbsp;type="text/xsl"&nbsp;href="grade.xsl"?&nbsp;&gt;<br><br>&lt;&nbsp;document&nbsp;&gt;<br><br>&lt;&nbsp;grade&nbsp;&gt;<br><br>&lt;&nbsp;name&nbsp;&gt;大胖&lt;&nbsp;/name&nbsp;&gt;&lt;&nbsp;english&nbsp;&gt;80&lt;&nbsp;/english&nbsp;&gt;<br><br>&lt;&nbsp;math&nbsp;&gt;90&lt;&nbsp;/math&nbsp;&gt;&lt;&nbsp;chymest&nbsp;&gt;90&lt;&nbsp;/chymest&nbsp;&gt;<br><br>&lt;&nbsp;/grade&nbsp;&gt;<br><br>&lt;&nbsp;grade&nbsp;&gt;<br><br>&lt;&nbsp;name&nbsp;&gt;小花&lt;&nbsp;/name&nbsp;&gt;&lt;&nbsp;english&nbsp;&gt;98&lt;&nbsp;/english&nbsp;&gt;<br><br>&lt;&nbsp;math&nbsp;&gt;70&lt;&nbsp;/math&nbsp;&gt;&lt;&nbsp;chymest&nbsp;&gt;85&lt;&nbsp;/chymest&nbsp;&gt;<br><br>&lt;&nbsp;/grade&nbsp;&gt;<br><br>&lt;&nbsp;/document&nbsp;&gt;<br><br>　　为实现按分数分等级显示，其XSL文档（文件名：grade.xsl）内容如下：&nbsp;<br><br>&lt;&nbsp;?xml&nbsp;version="1.0"&nbsp;encoding="GB2312"?&nbsp;&gt;<br><br>&lt;&nbsp;xsl:stylesheet&nbsp;xmlns:xsl="<a href="http://www.w3.org/TR/WD-xsl%22" target=_blank href_cetemp='http://www.w3.org/TR/WD-xsl"'><font color=#002c99><u>http://www.w3.org/TR/WD-xsl"</u></font></a> &nbsp;&gt;<br><br>&lt;&nbsp;xsl:template&nbsp;match="/"&nbsp;&gt;<br><br>&lt;&nbsp;HTML&nbsp;&gt;<br><br>&lt;&nbsp;HEAD&nbsp;&gt;&lt;&nbsp;TITLE&nbsp;&gt;成绩单&lt;&nbsp;/TITLE&nbsp;&gt;&lt;&nbsp;/HEAD&nbsp;&gt;<br><br>&lt;&nbsp;BODY&nbsp;&gt;&lt;&nbsp;xsl:apply-templates&nbsp;select="document"/&nbsp;&gt;&lt;&nbsp;/BODY&nbsp;&gt;<br><br>&lt;&nbsp;/HTML&nbsp;&gt;<br><br>&lt;&nbsp;/xsl:template&nbsp;&gt;<br><br>&lt;&nbsp;xsl:template&nbsp;match="document"&nbsp;&gt;<br><br>&lt;&nbsp;TABLE&nbsp;border="1"&nbsp;cellspacing="0"&nbsp;&gt;<br><br>&lt;&nbsp;TH&nbsp;&gt;姓名&lt;&nbsp;/TH&nbsp;&gt;&nbsp;&lt;&nbsp;TH&nbsp;&gt;英语&lt;&nbsp;/TH&nbsp;&gt;&lt;&nbsp;TH&nbsp;&gt;数学&lt;&nbsp;/TH&nbsp;&gt;&lt;&nbsp;TH&nbsp;&gt;化学&lt;&nbsp;/TH&nbsp;&gt;<br><br>&lt;&nbsp;xsl:apply-templates&nbsp;select="grade"/&nbsp;&gt;<br><br>&lt;&nbsp;/TABLE&nbsp;&gt;<br><br>&lt;&nbsp;/xsl:template&nbsp;&gt;<br><br>&lt;&nbsp;xsl:template&nbsp;match="grade"&nbsp;&gt;<br><br>&lt;&nbsp;TR&nbsp;&gt;<br><br>&lt;&nbsp;TD&nbsp;&gt;&lt;&nbsp;xsl:apply-templates&nbsp;select="name"/&nbsp;&gt;&lt;&nbsp;/TD&nbsp;&gt;<br><br>&lt;&nbsp;TD&nbsp;&gt;&lt;&nbsp;xsl:apply-templates&nbsp;select="english"/&nbsp;&gt;&lt;&nbsp;/TD&nbsp;&gt;<br><br>&lt;&nbsp;TD&nbsp;&gt;&lt;&nbsp;xsl:apply-templates&nbsp;select="math"/&nbsp;&gt;&lt;&nbsp;/TD&nbsp;&gt;<br><br>&lt;&nbsp;TD&nbsp;&gt;&lt;&nbsp;xsl:apply-templates&nbsp;select="chymest"/&nbsp;&gt;&lt;&nbsp;/TD&nbsp;&gt;<br><br>&lt;&nbsp;/TR&nbsp;&gt;<br><br>&lt;&nbsp;/xsl:template&nbsp;&gt;<br><br>&lt;&nbsp;xsl:template&nbsp;match="name"&nbsp;&gt;&lt;&nbsp;xsl:value-of/&nbsp;&gt;&lt;&nbsp;/xsl:template&nbsp;&gt;<br><br>&lt;&nbsp;xsl:template&nbsp;match="english|math|chymest"&nbsp;&gt;<br><br>&lt;&nbsp;xsl:choose&nbsp;&gt;<br><br>&lt;&nbsp;xsl:when&nbsp;test=".[value()&nbsp;$gt$&nbsp;85]"&nbsp;&gt;优秀&lt;&nbsp;/xsl:when&nbsp;&gt;<br><br>&lt;&nbsp;xsl:when&nbsp;test=".[value()&nbsp;$gt$&nbsp;70]"&nbsp;&gt;一般&lt;&nbsp;/xsl:when&nbsp;&gt;<br><br>&lt;&nbsp;xsl:when&nbsp;test=".[value()&nbsp;$gt$&nbsp;60]"&nbsp;&gt;起格&lt;&nbsp;/xsl:when&nbsp;&gt;<br><br>&lt;&nbsp;xsl:otherwise&nbsp;&gt;不起格&lt;&nbsp;/xsl:otherwise&nbsp;&gt;<br><br>&lt;&nbsp;/xsl:choose&nbsp;&gt;<br><br>&lt;&nbsp;/xsl:template&nbsp;&gt;<br><br>&lt;&nbsp;/xsl:stylesheet&nbsp;&gt;<br><br>说明：<br><br>　　在&lt;&nbsp;xsl:choose&nbsp;&gt;选择中，从第一个&lt;&nbsp;xsl:when&nbsp;&gt;开始，逐个测试，直到满足一个测试条件就将其中的内容输出，不再测试后面的条件；如果不满足任何一个条件，则输出&lt;&nbsp;xsl:otherwise&nbsp;&gt;中的内容。<br><br>　　标记对&lt;&nbsp;xsl:when&nbsp;&gt;&lt;&nbsp;/xsl:when&nbsp;&gt;与&lt;&nbsp;xsl:otherwise&nbsp;&gt;&lt;&nbsp;/xsl:otherwise&nbsp;&gt;中可嵌套&lt;&nbsp;xsl:if&nbsp;&gt;或&lt;&nbsp;xsl:choose&nbsp;&gt;。<br><br>注：如果拷贝源代码，请将空格删除<br><br>跟我学XSL（六）&nbsp;&nbsp;（返回标题）&nbsp;<br><br>2000-05-08&#183;&nbsp;禹希初&#183;CPCW<br><br>运算符、关系与逻辑运算符，特殊字符等<br><br>　　今天我们学习XSL的各种运算符，满足编写更大灵活性的XSL样式的要求。<br><br>表一、运算符与特殊字符<br><br>运算符&nbsp;描述&nbsp;<br><br>/&nbsp;选择子元素，返回左侧元素的直接子元素；如果&#8220;/&#8221;位于最左侧表示选择根结点的直接子元素&nbsp;<br><br>//&nbsp;递归下降，不论深度，搜索指定的元素；如果位于最左侧表示从根结点出发递归下降搜索指定元素&nbsp;<br><br>.&nbsp;表示当前元素&nbsp;<br><br>*&nbsp;通配符，选择任意元素，不考虑名字&nbsp;<br><br>@&nbsp;取得属性值，作为属性名的前缀&nbsp;<br><br>@*&nbsp;通配符，选择任意属性，不考虑名字&nbsp;<br><br>:&nbsp;名字作用范围分隔符，将名字作用范围前缀与元素或属性名分隔开来&nbsp;<br><br>!*&nbsp;在相关节点上应用指定方法&nbsp;<br><br>(&nbsp;)*&nbsp;分组，明确指定优先顺序&nbsp;<br><br>[&nbsp;]&nbsp;应用过滤样式&nbsp;<br><br>[&nbsp;]*&nbsp;下标运算符，用于在集合中指示元素&nbsp;<br><br>表二、逻辑运算符<br><br>比较运算符&nbsp;可选方式&nbsp;描述&nbsp;<br><br>and&nbsp;$and$或&nbsp;逻辑与&nbsp;<br><br>or&nbsp;$or$或||&nbsp;逻辑或&nbsp;<br><br>not()&nbsp;$not$&nbsp;逻辑非&nbsp;<br><br>表三、关系运算符&nbsp;<br><br>=&nbsp;$eq$&nbsp;相等&nbsp;<br><br>=&nbsp;$ieq$&nbsp;相等（不区分大小写）&nbsp;<br><br>!=&nbsp;$ne$&nbsp;不等&nbsp;<br><br>$ine$&nbsp;不等（不区分大小写）&nbsp;<br><br>&lt;&nbsp;$lt$&nbsp;小于&nbsp;<br><br>$ilt$&nbsp;小于（不区分大小写）&nbsp;<br><br>&lt;&nbsp;=&nbsp;$le$&nbsp;小于等于&nbsp;<br><br>$ile$&nbsp;小于等于（不区分大小写）&nbsp;<br><br>&gt;&nbsp;$gt$&nbsp;大于&nbsp;<br><br>$igt$&nbsp;大于（不区分大小写）&nbsp;<br><br>&gt;=&nbsp;$ge$&nbsp;大于等于&nbsp;<br><br>$ige$&nbsp;大于等于（不区分大小写）&nbsp;<br><br>$all$&nbsp;集合运算符，如果集合中所有项目均满足条件则返回&#8220;真&#8221;&nbsp;<br><br>$any$&nbsp;集合运算符，如果集合中任意项目满足条件则返回&#8220;真&#8221;&nbsp;<br><br>|&nbsp;集合运算符，返回两个集合的联合&nbsp;<br><br>示例一：<br><br>　　从个人简历中寻找具有具有&#8220;WEB开发&#8221;技能的人的姓名与E-Mail。假设文档结构如下所示：&nbsp;<br><br>&lt;&nbsp;document&nbsp;&gt;<br><br>&lt;&nbsp;resume&nbsp;&gt;<br><br>&lt;&nbsp;name&nbsp;&gt;name&lt;&nbsp;/name&nbsp;&gt;<br><br>&lt;&nbsp;sex&nbsp;&gt;sex&lt;&nbsp;/sex&nbsp;&gt;<br><br>&lt;&nbsp;birthday&nbsp;&gt;birthday&lt;&nbsp;/birthday&nbsp;&gt;<br><br>&lt;&nbsp;skill&nbsp;&gt;skill1&lt;&nbsp;/skill&nbsp;&gt;<br><br>&lt;&nbsp;skill&nbsp;&gt;skill2&lt;&nbsp;/skill2&nbsp;&gt;<br><br>&#8230;&nbsp;<br><br>&lt;&nbsp;skill&nbsp;&gt;skilln&lt;&nbsp;/skill&nbsp;&gt;<br><br>&lt;&nbsp;/resume&nbsp;&gt;<br><br>&lt;&nbsp;resume&nbsp;&gt;<br><br>&#8230;&nbsp;<br><br>&lt;&nbsp;/resume&nbsp;&gt;<br><br>&#8230;&nbsp;<br><br>&lt;&nbsp;/document&nbsp;&gt;<br><br>　　为从以上结构的个人简历中寻找出所有具有&#8220;WEB开发&#8221;技能的人的姓名与E-Mail的XSL文档结构如下：&nbsp;<br><br>&lt;&nbsp;TABLE&nbsp;border="1"&nbsp;cellspacing="0"&nbsp;&gt;<br><br>&lt;&nbsp;TH&nbsp;&gt;姓名&lt;&nbsp;/TH&nbsp;&gt;&lt;&nbsp;TH&nbsp;&gt;E-Mail&lt;&nbsp;/TH&nbsp;&gt;<br><br>&lt;&nbsp;xsl:for-each&nbsp;select="resume&nbsp;[&nbsp;$any$&nbsp;skill='WEB开发'&nbsp;]"&nbsp;&gt;<br><br>&lt;&nbsp;TR&nbsp;&gt;&lt;&nbsp;TD&nbsp;&gt;&lt;&nbsp;xsl:value-of&nbsp;select="name"/&nbsp;&gt;&lt;&nbsp;/TD&nbsp;&gt;<br><br>&lt;&nbsp;TD&nbsp;&gt;&lt;&nbsp;xsl:value-of&nbsp;select="E-Mail"/&nbsp;&gt;&lt;&nbsp;/TD&nbsp;&gt;<br><br>&lt;&nbsp;/TR&nbsp;&gt;<br><br>&lt;&nbsp;/xsl:for-each&nbsp;&gt;<br><br>&lt;&nbsp;/TABLE&nbsp;&gt;<br><br>说明：&nbsp;<br><br>1.[&nbsp;]&nbsp;───表示选择条件，只有满足条件的个人简历才被显示；&nbsp;<br><br>2.$any$&nbsp;──由于每个人有多种技能，故加$any$作为前缀，以使每个人所有技能都能被比较；&nbsp;<br><br>3.skill='WEB开发'&nbsp;──筛选条件<br><br>示例二、<br><br>　　仍上面的XML文档为例，如果欲选择1977/1/1之前出生的人的姓名、技能与E-Mail，相应的XSL文档结构如下（假定生日格式为yyyy/mm/dd）：&nbsp;<br><br>&lt;&nbsp;TABLE&nbsp;border="1"&nbsp;cellspacing="0"&nbsp;&gt;<br><br>&lt;&nbsp;TH&nbsp;&gt;姓名&lt;&nbsp;/TH&nbsp;&gt;&lt;&nbsp;TH&nbsp;&gt;技能&lt;&nbsp;/TH&nbsp;&gt;&lt;&nbsp;TH&nbsp;&gt;E-Mail&lt;&nbsp;/TH&nbsp;&gt;<br><br>&lt;&nbsp;xsl:for-each&nbsp;select="resume&nbsp;[&nbsp;birthday&nbsp;$lt$&nbsp;'1977/1/1'&nbsp;]"&nbsp;&gt;<br><br>&lt;&nbsp;TR&nbsp;&gt;<br><br>&lt;&nbsp;TD&nbsp;&gt;&lt;&nbsp;xsl:value-of&nbsp;select="name"/&nbsp;&gt;&lt;&nbsp;/TD&nbsp;&gt;<br><br>&lt;&nbsp;TD&nbsp;&gt;&lt;&nbsp;xsl:value-of&nbsp;select="skill&nbsp;[0]"/&nbsp;&gt;<br><br>&lt;&nbsp;xsl:for-each&nbsp;select="skill&nbsp;[index()&nbsp;&gt;0]"&nbsp;&gt;、&nbsp;<br><br>&lt;&nbsp;xsl:value-of&nbsp;select="."/&nbsp;&gt;<br><br>&lt;&nbsp;/xsl:for-each&nbsp;&gt;<br><br>&lt;&nbsp;/TD&nbsp;&gt;<br><br>&lt;&nbsp;TD&nbsp;&gt;&lt;&nbsp;xsl:value-of&nbsp;select="E-Mail"/&nbsp;&gt;&lt;&nbsp;/TD&nbsp;&gt;<br><br>&lt;&nbsp;/TR&nbsp;&gt;<br><br>&lt;&nbsp;/xsl:for-each&nbsp;&gt;<br><br>&lt;&nbsp;/TABLE&nbsp;&gt;<br><br>说明：&nbsp;<br><br>1.&nbsp;birthday&nbsp;$lt$&nbsp;'1977/1/1'&nbsp;──&nbsp;搜索条件，在此处使用&#8220;&lt;&nbsp;&#8221;会错误，故使用&#8220;$lt$&#8221;表示小于。&nbsp;<br><br>2.&nbsp;skill&nbsp;[0]&nbsp;───&nbsp;表示选择skill的第一项&nbsp;<br><br>3.&nbsp;skill&nbsp;[index()&nbsp;&gt;0]───表示选择skill的第二项以后（包括第二项）的项目&nbsp;<br><br>4.&nbsp;xsl:value-of&nbsp;select="."&nbsp;───&nbsp;表示选择当前标记的值<br><br>　　相信大家应该注意到，在前面以及本次的例子中出现了一些函数，如index()、formatIndex()、childNumber()，也许大家还不完全明了其中的含义吧？敬请关注下一课。<br><br>注：如果拷贝源代码，请将空格删除&nbsp;<br><br>跟我学XSL（七）&nbsp;&nbsp;（返回标题）&nbsp;<br><br>2000-05-09&#183;&nbsp;禹希初&#183;CPCW<br><br>XSL函数一<br><br>　　本期学习XSL样式方法，即可用于XSL元素&lt;&nbsp;xsl:for-each&nbsp;&gt;、&lt;&nbsp;xsl:value-of&nbsp;&gt;、&lt;&nbsp;xsl:template&nbsp;&gt;的select属性、&lt;&nbsp;xsl:apply-templates&nbsp;&gt;的match属性、&lt;&nbsp;xsl:if&nbsp;&gt;、&lt;&nbsp;xsl:when&nbsp;&gt;的test属性中，对元素的范围进行筛选，从而提供更大的灵活性。<br><br>　　XML与DHTML（动态HTML）一样，这些节点都是一个个对象，而且这些对象都是有层次的，从根节点开始构成一颗层次清淅的树状结构，这就形成了文档对象模型DOM，通过对象的属性、方法来达到访问控制XML节点的目的。<br><br>　　我们这里不打算就XML的DOM逐一详细阐述，因为这完全可以写成一个篇幅较多的教程，我们先就一些常见的方法作一些讨论，以期对DOM的对象方法有一个大致的了解。<br><br>　　注：从本期开始，所有示例不再提供完整源代码，如有不明白之处，请仔细阅读前面七期、并动手练手。<br><br>一、end()<br><br>含义：返回集合中最后一个元素。<br><br>示例：输出最后一份简历<br><br>假定XML文件格式为：<br><br>&#8230;&#8230;&lt;&nbsp;resume&nbsp;&gt;&#8230;&lt;&nbsp;/resume&nbsp;&gt;&#8230;&#8230;&lt;&nbsp;resume&nbsp;&gt;&#8230;&lt;&nbsp;/resume&nbsp;&gt;&#8230;&#8230;<br><br>相应XSL文件内容为：&nbsp;<br><br>&lt;&nbsp;xsl:for-each&nbsp;select="resume[end()]"&nbsp;&gt;&#8230;&#8230;&lt;&nbsp;/xsl:for-each&nbsp;&gt;<br><br>或&nbsp;<br><br>&lt;&nbsp;xsl:templates&nbsp;match="resume[end()]"&nbsp;&gt;&#8230;&#8230;&lt;&nbsp;/xsl:templates&nbsp;&gt;<br><br>或&nbsp;<br><br>&lt;&nbsp;xsl:apply-template&nbsp;select="resume[end()]"&nbsp;&gt;&#8230;&#8230;&lt;&nbsp;/xsl:apply-template&nbsp;&gt;<br><br>二、index()<br><br>含义：返回该元素在集合中的位置，返回值是一整数，其中第一个元素返回0<br><br>示例：返回前面三份简历&nbsp;<br><br>resume[index()&nbsp;$le$&nbsp;3]<br><br>注意：index()是与父元素相关的，请看下例：&nbsp;<br><br>&lt;&nbsp;x&nbsp;&gt;<br><br>&lt;&nbsp;y/&nbsp;&gt;<br><br>&lt;&nbsp;y/&nbsp;&gt;<br><br>&lt;&nbsp;/x&nbsp;&gt;<br><br>&lt;&nbsp;x&nbsp;&gt;<br><br>&lt;&nbsp;y/&nbsp;&gt;<br><br>&lt;&nbsp;y/&nbsp;&gt;<br><br>&lt;&nbsp;/x&nbsp;&gt;<br><br>返回所有&lt;&nbsp;x&nbsp;&gt;中的第一个&lt;&nbsp;y&nbsp;&gt;<br><br>x/y[index()=0]&nbsp;或x/y[0]<br><br>三、nodeName()<br><br>含义：返回元素的名字，即标记名<br><br>示例：选择任意元素，假如其名字（即标记名）等于&#8220;name&#8221;<br><br>*[nodeName()='name']&nbsp;或&nbsp;*[name]<br><br>四、number()<br><br>含义：将值转换为数值形式，如果不是数值则返回空，要求参数<br><br>示例：年龄(age)小于30岁的人的简历(resume)<br><br>resume[number(age)&nbsp;$lt$&nbsp;30]&nbsp;或resume[age&nbsp;$lt$&nbsp;30]<br><br>五、nodeType()<br><br>含义：返回结点类型，结果为是数值。以下是返回值列表：<br><br>结点类型&nbsp;结点类型值&nbsp;结点的字符形式描述&nbsp;<br><br>Element&nbsp;1&nbsp;'element'&nbsp;<br><br>Element&nbsp;Attribute&nbsp;2&nbsp;'attribute'&nbsp;<br><br>Markup-Delimited&nbsp;Region&nbsp;of&nbsp;Text&nbsp;3&nbsp;'text'&nbsp;<br><br>Processing&nbsp;Instruction&nbsp;7&nbsp;'processing_instruction'&nbsp;<br><br>Comment&nbsp;8&nbsp;'comment'&nbsp;<br><br>Document&nbsp;Entity&nbsp;9&nbsp;'document'&nbsp;<br><br>六、value()<br><br>含义：返回元素或属性的值<br><br>示例：value()是元素或属性的缺省方法，以下表示是等价&nbsp;<br><br>name!value()="NAME"与name="NAME"<br><br>@attr="attribute_value"与@attr="attribute_value"<br><br>注：@是属性前缀，@attr表示是属性attr<br><br>七、attribute()<br><br>含义：返回所有属性结点的集合，等价于&#8220;@*&#8221;<br><br>示例：寻找所有的resume元素，满足条件至少有一个属性的值为&#8220;ABC&#8221;<br><br>resume[$any$&nbsp;attribute()='ABC']或resume[$any$&nbsp;@*='ABC']<br><br>寻找所有的resume元素，满足条件至少有一个子元素有一个属性的值为&#8220;ABC&#8221;<br><br>resume[$any$&nbsp;*/attribute()='ABC']或resume[$any$&nbsp;*/@*='ABC']<br><br>八、comment()<br><br>含义：返回所有注释结点&nbsp;<br><br>示例：例如&nbsp;<br><br>resume[$any$&nbsp;comment()='禹希初的简历']<br><br>表示寻找含有注释语句&nbsp;<br><br>&lt;&nbsp;!--禹希初的简历--&nbsp;&gt;<br><br>的元素&lt;&nbsp;resume&nbsp;&gt;<br><br>九、cdata()<br><br>含义：返回所有CDATA类型的结点的集合<br><br>示例：例如&nbsp;<br><br>resume[$any$&nbsp;cdata()='禹希初的简历']<br><br>表示寻找含有下述语句（必须是直接子结点）&nbsp;<br><br>&lt;&nbsp;![CDATA[禹希初的简历]]&nbsp;&gt;<br><br>的元素&lt;&nbsp;resume&nbsp;&gt;<br><br>十、node()<br><br>含义：返回当前上下文环境中除根结点和属性结点以外的所有结点的集合，等价于<br><br>&#8220;*&nbsp;|&nbsp;pi()&nbsp;|&nbsp;comment()&nbsp;|&nbsp;text()&#8221;<br><br>示例：寻找所有元素resume，其最后一个结点的名字为"skill"<br><br>resume[node()[end()]!nodeName()='skill']<br><br>寻找所有resume元素的第一个结点：resume/node()[0]<br><br>十一、textnode()<br><br>含义：返回所有文本类型的结点的集合<br><br>示例：寻找每一个p元素的第二个文本结点&nbsp;<br><br>p/textnode(1)或p!textnode(1)<br><br>十二、text()<br><br>含义：返回所有表示文本字符串的结点的集合，等价于"cdata()|textnode()"；<br><br>　　本期的内容就介绍至此，另有一个函数date()在本人的机器上一试就发生错误使浏览器自动关闭，还有一个函数pi()本人尚未找到适当的应用方法，就不介绍了，下期将讲述如何XSL中使用脚本。<br><br>跟我学XSL（八）&nbsp;&nbsp;（返回标题）&nbsp;<br><br>2000-05-10&#183;&nbsp;禹希初&#183;CPCW<br><br>脚本与XSL的结合及应用<br><br>有时，我们可能会希望XML文档输出时能对其中内容加上一些统计信息或者如编号什么，利用前面的知识就不太容易实现了。今天将介绍两个新元素&lt;&nbsp;xsl:eval&nbsp;&gt;与&lt;&nbsp;xsl:script&nbsp;&gt;，使我们能轻松处理这个难题。&nbsp;<br><br>&lt;&nbsp;xsl:eval&nbsp;&gt;<br><br>含义：&nbsp;<br><br>计算脚本表达式，输出一个文本字符串&nbsp;<br><br>语法：&nbsp;<br><br>&lt;&nbsp;xsl:eval&nbsp;language="language-name"&nbsp;&gt;<br><br>属性：&nbsp;<br><br>language&nbsp;──&nbsp;规定所用脚本语言的名字，可用的属性有&#8220;JavaScript&#8221;、&#8220;Jscript&#8221;、&#8220;VBScript&#8221;、&#8220;VBS&#8221;等，缺省为&#8220;Jscript&#8221;。&nbsp;<br><br>&lt;&nbsp;xsl:script&nbsp;&gt;<br><br>含义：&nbsp;<br><br>声明全局变量或定义函数。&nbsp;<br><br>语法：&nbsp;<br><br>&lt;&nbsp;xsl:script&nbsp;language="language-name"&nbsp;&gt;<br><br>属性：<br><br>同&lt;&nbsp;xsl:eval&nbsp;&gt;<br><br>示例：<br><br>　　不知大家对于第四期《跟我学XML》中的例子是否还有印象？其中的XML文档并没有对简历编号，但输出中却加上了大写的罗马数字序号。今天将再举一稍为复杂一些的例子：<br><br>　　假如我们编写一份年终生产统计表，其中需要小计一项，常规的作法是事先将其算出来，现在不必了，我们可以只给出单项统计，显示时再统计小计一项。请找出《跟我学XML》的第五期，XML文件不必修改，对XSL文件的修改如下：&nbsp;<br><br>&#8230;&#8230;&nbsp;<br><br>&lt;&nbsp;xsl:template&nbsp;match="document"&nbsp;&gt;<br><br>&#8230;&#8230;&nbsp;<br><br>&lt;&nbsp;xsl:apply-templates&nbsp;select="report"/&nbsp;&gt;<br><br>&lt;&nbsp;TR&nbsp;&gt;&lt;&nbsp;TD&nbsp;&gt;小计&lt;&nbsp;/TD&nbsp;&gt;<br><br>&lt;&nbsp;TD&nbsp;&gt;&lt;&nbsp;xsl:eval&nbsp;&gt;total(this,"q1")&lt;&nbsp;/xsl:eval&nbsp;&gt;&lt;&nbsp;/TD&nbsp;&gt;<br><br>&lt;&nbsp;TD&nbsp;&gt;&lt;&nbsp;xsl:eval&nbsp;&gt;total(this,"q2")&lt;&nbsp;/xsl:eval&nbsp;&gt;&lt;&nbsp;/TD&nbsp;&gt;<br><br>&lt;&nbsp;TD&nbsp;&gt;&lt;&nbsp;xsl:eval&nbsp;&gt;total(this,"q3")&lt;&nbsp;/xsl:eval&nbsp;&gt;&lt;&nbsp;/TD&nbsp;&gt;<br><br>&lt;&nbsp;TD&nbsp;&gt;&lt;&nbsp;xsl:eval&nbsp;&gt;total(this,"q4")&lt;&nbsp;/xsl:eval&nbsp;&gt;&lt;&nbsp;/TD&nbsp;&gt;<br><br>&lt;&nbsp;/TR&nbsp;&gt;<br><br>&lt;&nbsp;/TABLE&nbsp;&gt;<br><br>&lt;&nbsp;xsl:script&nbsp;&gt;<br><br>function&nbsp;total(node,q){<br><br>temp=0;&nbsp;<br><br>mark='/document/report/'+q;<br><br>v=node.selectNodes(mark);<br><br>for(t=v.nextNode();t;t=v.nextNode()){<br><br>temp+=Number(t.text);<br><br>}<br><br>return&nbsp;temp;&nbsp;//小计值&nbsp;<br><br>}&nbsp;<br><br>&lt;&nbsp;/xsl:script&nbsp;&gt;<br><br>&lt;&nbsp;/xsl:template&nbsp;&gt;<br><br>说明：<br><br>　　黑体部分为添加部分，注意添加部分分为两部分，&lt;&nbsp;xsl:script&nbsp;&gt;&lt;&nbsp;/xsl:script&nbsp;&gt;必须置于&lt;&nbsp;/TABLE&nbsp;&gt;之后，切记。&nbsp;<br><br>selectNodes()&nbsp;──&nbsp;是XMLDOMObject的一个方法，返回文档中所有满足条件的结点的集合，条件与&lt;&nbsp;xsl:for-each&nbsp;&gt;和select属性的取值采用同样的写法，可以加筛选、下标等限制，如：<br><br>寻找一季度产量大于等于50的班组&nbsp;<br><br>/document/report/q1[value()&nbsp;$ge$&nbsp;50]<br><br>以上写法还有一个更简单的写法&nbsp;<br><br>//q1[value()&nbsp;$ge$&nbsp;50]<br><br>//表示从根结点出发遍历所有结点，寻找满足条件的结点，如果文档内有同名但意义不同的结点则不能用此种方法，非不得已不建议使用。以此为例，如果希望统计年总产量，则可以下述字符串寻找结点（建议使用最后一种，此种描述将精确找到需要汇总的数据）&nbsp;<br><br>//*[value()&nbsp;$gt$&nbsp;0]<br><br>或&nbsp;<br><br>//(q1|q2|q3|q4)<br><br>或&nbsp;<br><br>/document/report/(q1|q2|q3|q4)<br><br>nextNode()&nbsp;──&nbsp;返回结点集中的下一个结点&nbsp;<br><br>Number()&nbsp;──&nbsp;将提供的参数转换为数值<br><br>　　下期介绍XSL函数2，用于&lt;&nbsp;xsl:script&nbsp;&gt;及&lt;&nbsp;xsl:eval&nbsp;&gt;中，以及&lt;&nbsp;xsl:if&nbsp;&gt;和&lt;&nbsp;xsl:when&nbsp;&gt;的expr属性。建议读者熟悉JavaScript、Jscript、VBScript中至少一种，否你能用XSL完成的工作将十分有限。由于篇幅关系，此处不作详细介绍。&nbsp;<br><br>注：如果拷贝源代码，请将空格删除&nbsp;<br><br>Xlink介绍&nbsp;<br><br>2000-03-02&#183;&nbsp;蔡依纯&nbsp;译&#183;中文XML<br><br>　　如果在这个世界上每部电脑中的每个资料块都能够被识别、定址及连结，那将是多么令人振奋的事呢!Xink就是说明如何在网络上做到这点的规格文件。<br><br>　　HTML的连结<br><br>　　由於WWW的风行，大部分的人都熟悉超文字连结的基本观念，亦即是&#8220;一个连结具有两个端点及一个方向，两个端点我们通常称为Anchor。这个连结可以从一个起点连到任何一个网路资源的目标点，这些连结可能是一张图片，一卷影片，一段声音，一个程式，一篇HTML的文件，或其中的元素等等&#8221;。<br><br>　　假如你常使用浏览器，你一定会知道，当你在连结上按滑鼠的右键时，就会出现一个选单，而其中一个选择是&#8220;在新视窗开启&#8221;。<br><br>　　在HTML中，对於这些连结都是用一个「Anchor」的标志所做成。<br><br>　　如果你是撰写HTML的高手，你一定知道在head标志里有个特别的标志叫做link，它提供了多种的连结功能：比方像是连结到样式表（新的浏览器会提供使用者多一点选择，让其自行选择使用哪一个样式表），或是连结到有音乐的地方（当下载完毕後可自动地播放），抑或是连结到另一个网页（可使浏览器预先载入该网页，以省去等待的时间）等。<br><br>　　以上所描述的都是连结的功能，事实上，有很多其他的超文字连结功能是HTML没有办法做到的，即使如早期（1960年末至1970年初期）的超文字连结系统所提供的连结功能，HTML亦没办法做到。然而，HTML之所以会成功，是因为它使用最简单的方式去使用超连结，而且使用者并不　要特别的编辑器（Editor）便可制作网页。<br><br>　　多用途的连结！<br><br>　　有时当我们看到「连结」时，我们发现其实它看起并不像是连结，但事实上，为什么呢？许多的事物包括电子化地址、识别字、位址或是查询等，都可以有连结这个动作。当你想到两个资料间有&#8220;relationship&#8221;、&#8220;role&#8221;、&#8220;pointer&#8221;或是&#8220;has&nbsp;a&#8221;等关联性时，在XML（eXtensibleMarkupLanguage）中我们可以用「连结」的方法来加以标示。<br><br>　　读者们应有一个观念，在HTML4.0规格中，所定义的超文字连结标准，并不是就是连结的所有特性，所以在这里我们将对连结做更清楚的定义：<br><br>　　1.一个连结可以有一个、二个甚至是很多个ends，而每一个end都可以是指标，事实上连结本身可以很明确地指定是外部（externally）连结，因而连接到每一个end。<br><br>　　2.一个连结并不　一定要有方向，但它也可以有很多或是没有方向，除此之外，连结的方向不　要一定得从&#8220;context&#8221;到&#8220;part&#8221;才行。<br><br>　　3.连结的end可以是某一范围，不一定是要连结到整个resource或某一地方。<br><br>　　4.连结点的表现方式乃视连结资料的角色而定，「撷取」和「取代」只是可能性的行为之一。是故，使用者设定连结为撷取资料并取代画面只是连结功能的表现之一。<br><br>　　XML连结对我们有什么用呢？简言之，像是资料模型化、资料交换、超文字连结或是任何不同关系的资料型态上，都可以派上用场。<br><br>　　Xlinks有一重要功能就是建立「topicmaps」，这是一种依据metadata连结到种种不同网路资源的方式。Topicmaps允许不同的资料有外在的注解（External&nbsp;Annotation）。因此，我们可以说Topicmaps是有结构性的metadata，而依据各特性关联主题，可以连结到不同的网路资源。<br><br>　　Xlinks<br><br>Xlink定义了几种常用的连结型态：Simple、Extended、Group和Document。&nbsp;<br><br>1.Simple的用法比较接近在HTML内a标志的用法（如下HTML的写法所示）。&nbsp;<br><br>2.Extended的用法包含arc和locator的元素，并允许各种种类的扩充连结。&nbsp;<br><br>3.Group和document的用法，是让群组连结到一些特别的文件。<br><br>以下我们将说明Simple的语法，有两种方法可以知道一个连结是否是Xlink：&nbsp;<br><br>1.直接使用simple字眼；&nbsp;<br><br>2.以xlink：type表示。<br><br>让我们来看看下面Simple的例子：&nbsp;<br><br>1.以HTML的写法如下：&nbsp;<br><br>2.以Xlink的写法：<br><br>　　同样一个连结，另一种Xlink也可以写成：<br><br>　　xmlns：xlink属性是一个名称　域（Namespaces）宣告的例子，而所谓的名称　域，是方便使用者同时使用数个文件型别宣告（Document&nbsp;TypeDeclaration）之机制，至於这样的做法，我们相信在未来之HTML版本中，也会朝这一方向努力。<br><br>　　也许我们觉得很奇怪，为什么这些arcs会接在一起，而形成extendedlink呢？有些人可能比较喜欢（图二）的写法，因为这种连结并没有&#8220;from&#8221;和&#8220;to&#8221;，只有href的地址。<br><br>　　在locator的定义中包含两个原性：href和role。href属性包含URL，role属性则包含了如何去使用连结的关键字。<br><br>　　Xlink扩展了URIs的使用，其中actuate和show对於Xlink来说是非常重要的属性，原因如下：<br><br>　　1.actuate的属性可以说明Link是自动地或人工地(user-command)追踪。<br><br>　　2.show的属性说明另一端的连结是　要显示一个新（new）的视窗,或是取代（replace）成目前的视窗，或是　要剖析的（若该连结连结到XML文件）。<br><br>　　对于HTML的高手来说，上述href属性的用法较不平常，这是因为含有查询条件的正确URL，而它的主要目的是查询文件。<br><br>　　这一种URL使用了一个很特别的语法，就是在URL之前放问号（？）来查询，许多指向资料库的连结都用这个技巧。<br><br>　　W3C正在发展中的Xpointer是一种特殊的查询，也是Xlink推展的一部份。Xpointer的语法是?xptr=加上XML&nbsp;PathExpression【像是id（phone2）】。从上面的例子中看来，id指到唯一识别字phone2。（这个跟xlink:arc的from和to的用意一样）。&nbsp;<br><br>XMLPathExpression可让我们以不同种类的标准来选择某一元素树状结构式（Elementtreeofstructure&nbsp;data）特殊分枝。 
<img src ="http://www.cnitblog.com/stomic/aggbug/30954.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/stomic/" target="_blank">大话人生</a> 2007-07-31 03:09 <a href="http://www.cnitblog.com/stomic/archive/2007/07/31/30954.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>