﻿<?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>BlogJava-飞云小侠之风儿吹过-随笔分类-Java</title><link>http://www.blogjava.net/scud/category/3187.html</link><description>山谷里鸟语花香,溪水潺潺</description><language>zh-cn</language><lastBuildDate>Sat, 06 Nov 2010 15:45:19 GMT</lastBuildDate><pubDate>Sat, 06 Nov 2010 15:45:19 GMT</pubDate><ttl>60</ttl><item><title>MAVEN:如何为开发和生产环境建立不同的配置文件 --我的简洁方案</title><link>http://www.blogjava.net/scud/archive/2010/10/27/336326.html</link><dc:creator>Scud(飞云小侠)</dc:creator><author>Scud(飞云小侠)</author><pubDate>Wed, 27 Oct 2010 14:31:00 GMT</pubDate><guid>http://www.blogjava.net/scud/archive/2010/10/27/336326.html</guid><wfw:comment>http://www.blogjava.net/scud/comments/336326.html</wfw:comment><comments>http://www.blogjava.net/scud/archive/2010/10/27/336326.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/scud/comments/commentRss/336326.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/scud/services/trackbacks/336326.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 其实也是最近才看Maven, 以前都是用ant+ivy, 对于轻量级的项目来说足够了, 而且非常灵活.看了看Maven, 约定.... 现在编程都说约定, 约定是挺好, 问题是超出约定的事情太多了, 到头来还要依赖其他东西, 真不想用maven啊.以前我们开发环境和生产环境的配置文件都是单独分开目录存放的, ant脚本搞个变量就自动打包不同的文件了. 我觉得管理起来也很容易, 所以...&nbsp;&nbsp;<a href='http://www.blogjava.net/scud/archive/2010/10/27/336326.html'>阅读全文</a><img src ="http://www.blogjava.net/scud/aggbug/336326.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/scud/" target="_blank">Scud(飞云小侠)</a> 2010-10-27 22:31 <a href="http://www.blogjava.net/scud/archive/2010/10/27/336326.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>对搜索引擎同义词支持的实验, 分析模拟</title><link>http://www.blogjava.net/scud/archive/2010/08/16/328950.html</link><dc:creator>Scud(飞云小侠)</dc:creator><author>Scud(飞云小侠)</author><pubDate>Mon, 16 Aug 2010 01:26:00 GMT</pubDate><guid>http://www.blogjava.net/scud/archive/2010/08/16/328950.html</guid><wfw:comment>http://www.blogjava.net/scud/comments/328950.html</wfw:comment><comments>http://www.blogjava.net/scud/archive/2010/08/16/328950.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/scud/comments/commentRss/328950.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/scud/services/trackbacks/328950.html</trackback:ping><description><![CDATA[<br />
今天偶尔看到一个同义词库, 想到这个有什么用途哪? 肯定是用来判断2句话, 2篇文章的相似性的.<br />
<br />
它对搜索引擎,对论文抄袭鉴定系统肯定有用, 于是去搜索引擎试了试, 结果大失所望失望, 貌似google,bing,baidu对同义词没有做处理, 感觉是很简单的东西, 竟然没有做相关处理.<br />
<br />
而且不仅仅是没有做同义词处理, 相关度方面也很差, 真是很奇怪的事情.<br />
<br />
<br />
我们随便找一句话: (从google的桌面工具文档里)<br />
<br />
A: "我们十分关注您的安全并为此推出了一项功能", <br />
<br />
对应样本为: <br />
<br />
B: "我们非常关注您的安全并为此推出了一项功能"<br />
<br />
<br />
我们搜索一下, 可以发现 A 可以匹配的很好, 如果改成B, 发现和A匹配的第一项不见了, 按照正常猜想即使改了一个词 相关度应该还是很高, 不知道为什么会这样.<br />
<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/scud/search/google_search_a.jpg" height="425" width="666" /><br />
<br />
<br />
替换其中一个同义词: (发现原来的网页不在前面了, 翻了几页也没有找到)<br />
<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/scud/search/google_search_b.jpg" height="467" width="664" /><br />
<br />
<br />
<br />
我们暂且不考虑 "大胜美国队" 和 "大败美国队"的语义分析, 但是上面的结果肯定不尽人意, 因为你可能需要考虑所有同义词, 否则可能就错过你想要的结果.<br />
<br />
<br />
<br />
下面我们做一个简单的分析和模拟来实现同义词的相关逻辑, 假设的流程如下:<br />
<ul>
    <li>
    &nbsp;&nbsp; &nbsp;首先我们要有同义词对应表(多对多,可以有权重)</li>
    <li>
    &nbsp;&nbsp; &nbsp;收录网页时把相应同义词映射到同一个词, 当然可以映射多个</li>
    <li>
    &nbsp;&nbsp; &nbsp;在搜索时先预处理用户输入的内容</li>
    <li>
    &nbsp;&nbsp; &nbsp;根据匹配算法计算</li>
</ul>
<br />
<br />
1. 同义词表结构如下<br />
<br />
一百分 --&gt;满分, 0.8<br />
十分 --&gt; 满分, 0.8<br />
<br />
十分 --&gt; 非常, 0.95<br />
特别 --&gt; 非常, 0.9<br />
格外 --&gt; 非常, 0.9<br />
<br />
关心 --&gt; 关注, 0.95<br />
注意 --&gt; 关注, 0.85<br />
<br />
......<br />
<br />
所有同义词映射到同一个词语, 并赋予一个权重. 当然还有多义词的问题, 会出现多个映射.<br />
<br />
当然同义词的整理也是个巨大的工作量, 网上也有一些词库.<br />
<br />
<br />
2. 根据同义词库的映射 <br />
<br />
&nbsp;&nbsp; &nbsp;原内容: 我们十分关注您的安全并为此推出了一项功能<br />
&nbsp;&nbsp; &nbsp;映射后: 我们 满分*0.8|非常*0.95|(十分) 关注您的安全并为此推出了一项功能<br />
<br />
&nbsp;&nbsp; &nbsp;"|"表示有多个选择, "()"表示为原内容.<br />
<br />
3. 对输入内容的分析映射<br />
<br />
&nbsp;&nbsp; &nbsp;用户输入: 我们非常关心您的安全并为此推出了一项功能&nbsp;&nbsp; &nbsp;<br />
&nbsp;&nbsp; &nbsp;分析映射: 我们非常 关注*0.95|(关心) 您的安全并为此推出了一项功能<br />
<br />
4. 匹配查找<br />
&nbsp; &nbsp;<br />
&nbsp;&nbsp; 匹配查找就是搜索引擎核心的逻辑了, 当然在遇到 "满分*0.8|非常*0.95|(十分)" 需要增加同义词判断逻辑, 根据2个权重可以得出一个同义词的匹配度, 然后继续分析即可.<br />
<br />
<br />
<br />
以上只是一个非常简单的分析模拟, 和实际的搜索引擎逻辑差别非常大, 仅供参考.<br />
<br />
<img src ="http://www.blogjava.net/scud/aggbug/328950.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/scud/" target="_blank">Scud(飞云小侠)</a> 2010-08-16 09:26 <a href="http://www.blogjava.net/scud/archive/2010/08/16/328950.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>不重复的排列组合示例</title><link>http://www.blogjava.net/scud/archive/2010/07/29/327395.html</link><dc:creator>Scud(飞云小侠)</dc:creator><author>Scud(飞云小侠)</author><pubDate>Thu, 29 Jul 2010 01:55:00 GMT</pubDate><guid>http://www.blogjava.net/scud/archive/2010/07/29/327395.html</guid><wfw:comment>http://www.blogjava.net/scud/comments/327395.html</wfw:comment><comments>http://www.blogjava.net/scud/archive/2010/07/29/327395.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/scud/comments/commentRss/327395.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/scud/services/trackbacks/327395.html</trackback:ping><description><![CDATA[昨天看到个帖子, 然后想了想写出一段程序来.&nbsp; 有空该补补排列组合的知识了.<br />
<br />
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #008000;">/**</span><span style="color: #008000;"><br />
</span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #008000;">&nbsp;*&nbsp;各字符不重复的组合,&nbsp;组合数小于等于最大可能性(否则就重复了).<br />
</span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #008000;">&nbsp;*&nbsp;<br />
</span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #008000;">&nbsp;*&nbsp;</span><span style="color: #808080;">@author</span><span style="color: #008000;">&nbsp;scud(飞云)<br />
</span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #008000;">&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;ShortCombineTest<br />
</span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">{<br />
</span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;count&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;main(String[]&nbsp;args)<br />
</span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br />
</span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;s&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">123456</span><span style="color: #000000;">"</span><span style="color: #000000;">;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">all&nbsp;items&nbsp;content</span><span style="color: #008000;"><br />
</span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;howmany&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">3</span><span style="color: #000000;">;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">how&nbsp;many&nbsp;object</span><span style="color: #008000;"><br />
</span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">[]&nbsp;c&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;s.toCharArray();<br />
</span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">[]&nbsp;dest&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">[howmany];<br />
</span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">18</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;combine(c,&nbsp;dest,&nbsp;howmany,&nbsp;s.length(),&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">);<br />
</span><span style="color: #008080;">19</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">20</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000;">"</span><span style="color: #000000;">max&nbsp;combine：</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;count);<br />
</span><span style="color: #008080;">21</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080;">22</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">23</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;combine(</span><span style="color: #0000ff;">char</span><span style="color: #000000;">[]&nbsp;array,&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">[]&nbsp;dest,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;howmany,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;maxitem,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;index)<br />
</span><span style="color: #008080;">24</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br />
</span><span style="color: #008080;">25</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">break&nbsp;&amp;&nbsp;end</span><span style="color: #008000;"><br />
</span><span style="color: #008080;">26</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(index&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;howmany)<br />
</span><span style="color: #008080;">27</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
</span><span style="color: #008080;">28</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(dest);<br />
</span><span style="color: #008080;">29</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;count</span><span style="color: #000000;">++</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">30</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">31</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080;">32</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">33</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">(array.length</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">0</span><span style="color: #000000;">)<br />
</span><span style="color: #008080;">34</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
</span><span style="color: #008080;">35</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dest[index]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;array[</span><span style="color: #000000;">0</span><span style="color: #000000;">];<br />
</span><span style="color: #008080;">36</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">[]&nbsp;nextarray&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;getLeftChar(array,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">);<br />
</span><span style="color: #008080;">37</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;nextarray;<br />
</span><span style="color: #008080;">38</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;combine(nextarray,&nbsp;dest,&nbsp;howmany,&nbsp;maxitem,&nbsp;index&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">);<br />
</span><span style="color: #008080;">39</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080;">40</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080;">41</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">42</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">[]&nbsp;getLeftChar(</span><span style="color: #0000ff;">char</span><span style="color: #000000;">[]&nbsp;c,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;index)<br />
</span><span style="color: #008080;">43</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br />
</span><span style="color: #008080;">44</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">[]&nbsp;left&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">[c.length&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">];<br />
</span><span style="color: #008080;">45</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">46</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">,&nbsp;j&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;c.length;&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)<br />
</span><span style="color: #008080;">47</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
</span><span style="color: #008080;">48</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(i&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;index)<br />
</span><span style="color: #008080;">49</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
</span><span style="color: #008080;">50</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;left[j]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;c[i];<br />
</span><span style="color: #008080;">51</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j</span><span style="color: #000000;">++</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">52</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080;">53</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080;">54</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">55</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;left;<br />
</span><span style="color: #008080;">56</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080;">57</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">58</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">59</span>&nbsp;<span style="color: #000000;">}<br />
</span><span style="color: #008080;">60</span>&nbsp;</div>
<br />
<br />
<img src ="http://www.blogjava.net/scud/aggbug/327395.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/scud/" target="_blank">Scud(飞云小侠)</a> 2010-07-29 09:55 <a href="http://www.blogjava.net/scud/archive/2010/07/29/327395.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>最近在编写DBHelper的文档</title><link>http://www.blogjava.net/scud/archive/2006/02/20/31634.html</link><dc:creator>Scud(飞云小侠)</dc:creator><author>Scud(飞云小侠)</author><pubDate>Mon, 20 Feb 2006 05:54:00 GMT</pubDate><guid>http://www.blogjava.net/scud/archive/2006/02/20/31634.html</guid><wfw:comment>http://www.blogjava.net/scud/comments/31634.html</wfw:comment><comments>http://www.blogjava.net/scud/archive/2006/02/20/31634.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/scud/comments/commentRss/31634.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/scud/services/trackbacks/31634.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: DBHelper是一个自己一直在用的一个JDBC的工具包,虽然比不上Hibernate那么好,但是简单,方便,也用了好多年了<br>&nbsp;&nbsp;<a href='http://www.blogjava.net/scud/archive/2006/02/20/31634.html'>阅读全文</a><img src ="http://www.blogjava.net/scud/aggbug/31634.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/scud/" target="_blank">Scud(飞云小侠)</a> 2006-02-20 13:54 <a href="http://www.blogjava.net/scud/archive/2006/02/20/31634.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>读"Under the Hood of J2EE Clustering" J2EE集群</title><link>http://www.blogjava.net/scud/archive/2005/09/28/14362.html</link><dc:creator>Scud(飞云小侠)</dc:creator><author>Scud(飞云小侠)</author><pubDate>Wed, 28 Sep 2005 15:53:00 GMT</pubDate><guid>http://www.blogjava.net/scud/archive/2005/09/28/14362.html</guid><wfw:comment>http://www.blogjava.net/scud/comments/14362.html</wfw:comment><comments>http://www.blogjava.net/scud/archive/2005/09/28/14362.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/scud/comments/commentRss/14362.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/scud/services/trackbacks/14362.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 读"Under the Hood of J2EE Clustering" J2EE集群&nbsp;&nbsp;<a href='http://www.blogjava.net/scud/archive/2005/09/28/14362.html'>阅读全文</a><img src ="http://www.blogjava.net/scud/aggbug/14362.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/scud/" target="_blank">Scud(飞云小侠)</a> 2005-09-28 23:53 <a href="http://www.blogjava.net/scud/archive/2005/09/28/14362.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>几个提高代码质量,检查代码规范的工具</title><link>http://www.blogjava.net/scud/archive/2005/08/29/11422.html</link><dc:creator>Scud(飞云小侠)</dc:creator><author>Scud(飞云小侠)</author><pubDate>Mon, 29 Aug 2005 03:49:00 GMT</pubDate><guid>http://www.blogjava.net/scud/archive/2005/08/29/11422.html</guid><wfw:comment>http://www.blogjava.net/scud/comments/11422.html</wfw:comment><comments>http://www.blogjava.net/scud/archive/2005/08/29/11422.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/scud/comments/commentRss/11422.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/scud/services/trackbacks/11422.html</trackback:ping><description><![CDATA[<P><BR><STRONG>1.FindBugs:查错</STRONG><BR>&nbsp;目前版本0.9.1,有for eclipse的插件. 网址是<A href="http://findbugs.sourceforge.net/">http://findbugs.sourceforge.net</A>.<BR>&nbsp;<BR>&nbsp;工作原理:检查程序生成的class的工具.<BR>&nbsp;<BR>&nbsp;界面:独立运行的提供图形界面,很友好,有bug报告.<BR>&nbsp;<BR>&nbsp;可用性:大多数提示有用,值得改<BR>&nbsp;<BR>&nbsp;插件:<BR>&nbsp;&nbsp;可以设置基本和检查的错误类别.<BR>&nbsp;&nbsp;插件保存设置有问题,我是关闭项目后台修改了配置文件,在装入才成功改了配置的. <BR>&nbsp;&nbsp;bug临时解决: 使用独立的findbugs设置规则,然后到C:\Documents and Settings\XXX\下找.Findbugs_prefs,然后改名覆盖eclipse project下的.fbprefs (先关闭你的project)<BR>&nbsp;<BR>&nbsp;配置没有查找功能,不过缩写能让我们很快找到某个规则<BR>&nbsp;<BR><STRONG>2.PMD:主要是查错</STRONG><BR>&nbsp;目前版本3.2,有for eclipse以及其他ide的插件.网址是<A href="http://pmd.sourceforge.net/">http://pmd.sourceforge.net</A><BR>&nbsp;工作原理:检查源码 <BR>&nbsp;可用性:一部分值得修改,有些过于严格<BR>&nbsp;界面:独立运行的是命令行界面,命令比较简单.<BR>&nbsp;插件:可以配置规则,有一个独立的窗口显示提示,分5级提示,很友好<BR>&nbsp;<BR>&nbsp;使用:建立自己的规范,然后用于实际使用中.<BR>&nbsp;<BR><STRONG>3.CheckStyle:主要查代码规范</STRONG><BR>&nbsp;目前版本4.0 beta 5,有for eclipse的插件.网址是<A href="http://checkstyle.sourceforge.net/">http://checkstyle.sourceforge.net</A>.<BR>&nbsp;工作原理:检查源码,对javadoc,书写格式等进行检查.<BR>&nbsp;规则定义:默认的规则是sun的编码规范.不过按照sun的规则则过于严格,而且每个公司也有自己的规范,和sun的不同,所以需要自定义规范.&nbsp;</P>
<P><STRONG>4.JTest 重量级的商业工具</STRONG><BR>&nbsp;目前版本7.0.7,有for eclipse的插件.网址是<A href="http://www.parasoft.com/">http://www.parasoft.com/</A><BR>&nbsp;<BR>&nbsp;不推荐使用,不过功能强大,可以进行代码检查,可以自动生成单元测试和进行单元测试.(不过就是太慢了,而且生成的单元测试没太大用途)<BR>&nbsp;<BR>&nbsp;<BR>&nbsp;</P>
<P><STRONG>使用感觉:</STRONG></P>
<P>&nbsp;安装上插件后,对自己的项目进行检查,发现警告太多了,有点发蒙的感觉.不过把警告看一遍,觉得都很有道理,有些也确实是一些错误.<BR>&nbsp;当然PMD和CheckStyle的规范太严格,最后还是配置了一下.<BR>&nbsp;<BR>&nbsp;通过改正警告,感觉还是不错,至少可以说自己的代码可以通过工具的检测了.<BR>&nbsp;<BR>&nbsp;当然基础代码和项目代码还是不一样的,基础代码往往比较复杂,所以和普通项目代码的规范应该有所不同.有些规则只能用在普通代码上,用在基础类代码上往往没法处理.<BR>&nbsp;<BR><STRONG>其他</STRONG></P>
<P>代码查错推荐使用Findbugs和PMD,代码书写规范推荐使用CheckStyle进行检查.这样不仅能查出一些基本的错误,也能提高项目的代码质量.对提高自己的代码水平也是非常好.</P>
<P>推荐项目组建立统一的规则,代码复查的时候就使用这些工具,省时省力.</P>
<P>实乃居家旅行,杀人越货必备之工具也.(因为肯定有人要骂你,呵呵,也是你找"差"的工具)</P>
<P><BR>&nbsp;<BR>&nbsp;</P><img src ="http://www.blogjava.net/scud/aggbug/11422.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/scud/" target="_blank">Scud(飞云小侠)</a> 2005-08-29 11:49 <a href="http://www.blogjava.net/scud/archive/2005/08/29/11422.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>分析XML中的CDATA类型在RSS中的使用</title><link>http://www.blogjava.net/scud/archive/2005/08/22/10723.html</link><dc:creator>Scud(飞云小侠)</dc:creator><author>Scud(飞云小侠)</author><pubDate>Mon, 22 Aug 2005 10:49:00 GMT</pubDate><guid>http://www.blogjava.net/scud/archive/2005/08/22/10723.html</guid><wfw:comment>http://www.blogjava.net/scud/comments/10723.html</wfw:comment><comments>http://www.blogjava.net/scud/archive/2005/08/22/10723.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/scud/comments/commentRss/10723.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/scud/services/trackbacks/10723.html</trackback:ping><description><![CDATA[<P>除经特别注明外,本站文章版权归JScud Develop团队或其原作者所有. <BR>转载请注明作者和来源.&nbsp;&nbsp;scud(飞云小侠)&nbsp;&nbsp;&nbsp;&nbsp;欢迎访问 <A href="http://www.jscud.com/" target=_blank>JScud Develop</A> </P><BR>
<P><BR>根据XML中CDATA类型的规范可以知道:"&amp;"和"&lt;"不需要也不能被转换. "&gt;" 如果出现在"]]&gt;" 的内容而不是表示结束时,必须被转义为&amp;gt;</P>
<P><FONT color=#ff0000>但是这样就存在一个问题,</FONT>如果我需要输入"]]&gt;",正确的处理是保存为"]]&amp;gt;",但是如果我想输入"]]&amp;gt;",那么应该如何保存哪? 我想了很久,除非加空格或者采用特殊的办法,否则是没有办法解决的.</P>
<P><STRONG>1.如果我们不考虑输入"]]&amp;gt;"的问题,来考虑一下"]]&gt;"的处理,看看各种XML解析器是如何处理的?</STRONG></P>
<P>xml解析器的测试包含2个部分:设置cdata类型的数据和读出cdata类型的数据.</P>
<P>首先我们写一个测试的例子,计划使用JDom 1.0和Dom4j来测试一下:</P>
<P>
<TABLE class=code cellSpacing=1 cellPadding=1 width="80%" align=center border=0>
<TBODY>
<TR>
<TD>&nbsp;package com.jscud.test;<BR>&nbsp;<BR>&nbsp;public class XmlTestBase<BR>&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp; public static String xmlpart = <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;"+<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "&lt;xml&gt;" +<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "&lt;test&gt;"+<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "&lt;hello&gt;&lt;![CDATA[ hello ]]&amp;gt; ]]&gt;&lt;/hello&gt;" +<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "&lt;/test&gt;" +<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "&lt;/xml&gt;";&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp; public static void print(String str)<BR>&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(str);<BR>&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;}&nbsp;</TD></TR></TBODY></TABLE><BR><BR><U>JDom测试的例子如下</U>:</P>
<P>
<TABLE class=code cellSpacing=1 cellPadding=1 width="80%" align=center border=0>
<TBODY>
<TR>
<TD>package com.jscud.test;<BR>&nbsp;<BR>&nbsp;import java.io.*;<BR>&nbsp;import org.jdom.*;<BR>&nbsp;import org.jdom.input.SAXBuilder;<BR>&nbsp;import org.jdom.output.*;<BR>&nbsp;<BR>&nbsp;<A>//@author</A> scud <A href="http://www.jscud.com/">http://www.jscud.com</A><BR>&nbsp;<BR>&nbsp;public class JDomXmlFileTest extends XmlTestBase<BR>&nbsp;{<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp; public static void main(String[] args) throws Exception<BR>&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; readDocument();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print("===========================");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; createDocument();<BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp; public static void readDocument() throws Exception<BR>&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Reader reader = new StringReader(xmlpart);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SAXBuilder builder = new SAXBuilder();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Document doc = builder.build(reader);<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Element aRoot = doc.getRootElement();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Element anode = aRoot.getChild("test").getChild("hello");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print(anode.getText());&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp; public static void createDocument() throws Exception<BR>&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Document doc = new Document();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; doc.setRootElement(new Element("root"));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CDATA node = new CDATA("hello alt=]]&amp;gt;");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //throw Exception<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //node.setText("hello]]&gt;");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Element ele = new Element("hello");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ele.setContent(node);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Element root = doc.getRootElement();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; root.getChildren().add(ele);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XMLOutputter outputter = new XMLOutputter();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Format aFormat = Format.getCompactFormat();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; aFormat.setEncoding("GB2312");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String sResult = outputter.outputString(doc.getRootElement().getChildren());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print(sResult);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;}&nbsp;</TD></TR></TBODY></TABLE></P>
<P>&nbsp;编译并运行上面的代码结果,我们可以看到JDom无法设置Cdata的值为"]]&gt;",会报异常.从xml字符串读出cdata的结果也没有把字串"]]&amp;gt;"翻译为"]]&gt;".</P>
<P><U>接着再来测试Dom4J</U>:</P>
<P>
<TABLE class=code cellSpacing=1 cellPadding=1 width="80%" align=center border=0>
<TBODY>
<TR>
<TD>package com.xml.test;<BR>&nbsp;<BR>&nbsp;import java.io.StringReader;<BR>&nbsp;<BR>&nbsp;import org.dom4j.*;<BR>&nbsp;import org.dom4j.io.SAXReader;<BR>&nbsp;import org.dom4j.tree.DefaultCDATA;<BR>&nbsp;<BR>&nbsp;/**<BR>&nbsp; * 测试XML的CData数据类型.<BR>&nbsp; * <BR>&nbsp; * @author scud <A href="http://www.jscud.com/">http://www.jscud.com</A><BR>&nbsp; *<BR>&nbsp; */<BR>&nbsp;<BR>&nbsp;public class Dom4jXmlTest extends XmlTestBase<BR>&nbsp;{&nbsp;&nbsp;&nbsp; <BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp; public static void main(String[] args) throws Exception<BR>&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; readDocument();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print("===========================");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; createDocument();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp; public static void createDocument()<BR>&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Document document = DocumentHelper.createDocument();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Element root = document.addElement( "root" );<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DefaultCDATA cdata = new DefaultCDATA("sample]]&gt;");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DefaultCDATA cdata2 = new DefaultCDATA("sample]]&amp;gt;");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Element anode = root.addElement("cdata");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; anode.add(cdata);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print(anode.getText());&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print(anode.asXML());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Element anode2 = root.addElement("cdata2");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; anode2.add(cdata2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print(anode2.getText());&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print(anode2.asXML());<BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp; public static void readDocument() throws Exception<BR>&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StringReader strreader = new StringReader(xmlpart);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SAXReader reader = new SAXReader();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Document document = reader.read(strreader);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Node node = document.selectSingleNode( "//test/hello" );<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print(node.getText());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print(node.getStringValue());<BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;}&nbsp;</TD></TR></TBODY></TABLE><BR>&nbsp;<BR>&nbsp;我们可以看到Dom4j也是没有做任何处理,输入的时候不作任何转换,原样输出,这样必然导致xml错误.读出的时候也没有做转换.</P>
<P>根据上面的测试我们可以得出结论:很多xml解析器没有正确解析cdata的数据,(jdom和dom4j用的人比较多),不要太相信这些解析器.</P>
<P>&nbsp;</P>
<P>2.<STRONG>我们再来看看阅读RSS的RSS阅读器</STRONG>吧,例如FeedDemon和POTU,我们准备了一个CData类型的description字段,来进行测试.</P>
<P>内容:</P>
<P>
<TABLE class=code cellSpacing=1 cellPadding=1 width="80%" align=center border=0>
<TBODY>
<TR>
<TD>&lt;?xml version="1.0" encoding="GB2312" ?&gt; <BR>&nbsp;&lt;rss version="2.0"&gt;<BR>&nbsp;&lt;channel&gt;<BR>&nbsp; &lt;title&gt;Some Where&lt;/title&gt; <BR>&nbsp; &lt;link&gt;http://www.jscud.com/&lt;/link&gt; <BR>&nbsp; &lt;description /&gt; <BR>&nbsp;&lt;item&gt;<BR>&nbsp; &lt;title&gt;Test&lt;/title&gt; <BR>&nbsp; &lt;link&gt;http://www.jscud.com&lt;/link&gt; <BR>&nbsp; &lt;author&gt;scud&lt;/author&gt; <BR>&nbsp; &lt;pubDate&gt;Mon, 22 Aug 2005 10:22:22 GMT&lt;/pubDate&gt; <BR>&nbsp; &lt;description&gt;&lt;![CDATA[<BR>&nbsp; &amp;lt;hr&amp;gt;<BR>&nbsp; ]]&amp;gt;<BR>&nbsp; ]]&gt;&lt;/description&gt; <BR>&nbsp; &lt;/item&gt;<BR>&nbsp; &lt;/channel&gt;<BR>&nbsp; &lt;/rss&gt;</TD></TR></TBODY></TABLE></P>
<P><BR><STRONG>结果</STRONG>:&nbsp;<BR>&nbsp;1.POTU没有做任何处理<BR>&nbsp;2.FeedDemon做了处理,不过同时也把其他的&amp;gt; &amp;lt;等等都翻译了,这就更不对了..<BR>&nbsp;</P>
<P><FONT color=#0000ff>本来我是打算在RSS里使用CDATA类型的description字段的,经过几番试验和测试,最后决定还是使用普通的description字段了,不在使用CDATA了.</FONT></P>
<P><FONT color=#ff0000>CDATA? 鸡肋乎? 呵呵</FONT></P>
<P>&nbsp;</P><img src ="http://www.blogjava.net/scud/aggbug/10723.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/scud/" target="_blank">Scud(飞云小侠)</a> 2005-08-22 18:49 <a href="http://www.blogjava.net/scud/archive/2005/08/22/10723.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用FreeMarker/Jsp(webwork)生成静态/动态RSS文件</title><link>http://www.blogjava.net/scud/archive/2005/08/19/10510.html</link><dc:creator>Scud(飞云小侠)</dc:creator><author>Scud(飞云小侠)</author><pubDate>Fri, 19 Aug 2005 06:11:00 GMT</pubDate><guid>http://www.blogjava.net/scud/archive/2005/08/19/10510.html</guid><wfw:comment>http://www.blogjava.net/scud/comments/10510.html</wfw:comment><comments>http://www.blogjava.net/scud/archive/2005/08/19/10510.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/scud/comments/commentRss/10510.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/scud/services/trackbacks/10510.html</trackback:ping><description><![CDATA[<P>scud(飞云小侠)&nbsp; <A href="http://www.jscud.com/">http://www.jscud.com</A> 转载请注明作者/来源</P>
<P>关键字:rss,freemarker,rss.xml,webwork2</P>
<P>RSS在网络上大行其道,各种网站都加上RSS支持,我最近也研究了一下,给我的文章也加上了RSS订阅.</P>
<P>RSS目前用的也有几个版本,很是混乱,下面以RSS2.0为例来说明.</P>
<P>网络上有个rsslibj库,是用来生成rss支持文件的,不过已经好久没有更新了,它是用xml的方式生成的.本文的例子不用到任何xml解析器,不过当然要知道最后生成的XML文件的格式才行,关于RSS规范,可以浏览一下 <A href="http://blogs.law.harvard.edu/tech/rss">http://blogs.law.harvard.edu/tech/rss</A> .</P>
<P>在计划生成RSS文件的时候,顺便搜索了一下JIRA和Confluence的程序,发现它们分别是用模板方式和JSP动态页面来展示的.于是我也想到两种方式:<BR>1.用FreeMarker生成静态文件,适用于更新不是很频繁的内容.<BR>2.用JSP动态展示,适合更新频率高,种类繁多的内容.</P>
<P>还是以本站的新闻举例,其中的新闻信息类参考 <A href="http://www.jscud.com/srun/news/viewhtml/3_2005_8/76.htm">http://www.jscud.com/srun/news/viewhtml/3_2005_8/76.htm</A> ,此处不在列出.</P>
<P>(一) 先说FreeMarker方式.</P>
<P>根据RSS的规范,得到模板如下:</P>
<P>
<TABLE class=code cellSpacing=1 cellPadding=1 width="80%" align=center border=0>
<TBODY>
<TR>
<TD>&lt;?xml version="1.0" encoding="UTF-8" ?&gt; <BR>&nbsp;&lt;rss version="2.0"&gt;<BR>&nbsp;&lt;channel&gt;<BR>&nbsp; &lt;title&gt;JScud Develop&lt;/title&gt; <BR>&nbsp; &lt;link&gt;http://www.jscud.com/&lt;/link&gt; <BR>&nbsp; &lt;language&gt;zh-cn&lt;/language&gt; <BR>&nbsp; &lt;description &gt;JScud Develop By Scud&lt;/description&gt;<BR>&nbsp; &lt;webMaster&gt;xxx@21cn.com(scud)&lt;/webMaster&gt; <BR>&nbsp; &lt;lastBuildDate&gt;${rssutil.formatRssDate(now)}&lt;/lastBuildDate&gt; <BR>&nbsp; &nbsp;<BR>&nbsp; &nbsp;&lt;#list newslist as onenews&gt;<BR>&nbsp; &lt;item&gt;<BR>&nbsp;&nbsp; &lt;title&gt;${onenews.title?xml}&lt;/title&gt;<BR>&nbsp;&nbsp; &lt;link&gt;http://www.jscud.com/srun/news/viewhtml/${onenews.htmlFilePath}/${onenews.nid}.htm&lt;/link&gt; <BR>&nbsp;&nbsp; &lt;pubDate&gt;${rssutil.formatRssDate(onenews.addtime)}&lt;/pubDate&gt; <BR>&nbsp;&nbsp; &lt;description&gt;&lt;![CDATA[<BR>&nbsp;&nbsp;${rssutil.formatRssCData(onenews.showContent)}<BR>&nbsp;&nbsp; ]]&gt;<BR>&nbsp;&nbsp; &lt;/description&gt;<BR>&nbsp;&nbsp; &lt;/item&gt;<BR>&nbsp;&lt;/#list&gt;<BR>&nbsp; &lt;/channel&gt;<BR>&nbsp;&lt;/rss&gt;</TD></TR></TBODY></TABLE></P>
<P>其中的网址和网站名称可以根据自己的实际情况修改.</P>
<P>我每次取出最新的20条文章来生成RSS,不过内容比较多,生成的RSS文件比较大,看到有的网站的description只是放了文章摘要的内容,这样文件就小多了.总之是根据自己的需求设计吧.</P>
<P>其中用到的RssUtil函数库的函数如下(日期的函数参考上一篇文章):<BR></P>
<P>
<TABLE class=code cellSpacing=1 cellPadding=1 width="80%" align=center border=0>
<TBODY>
<TR>
<TD>&nbsp;&nbsp;&nbsp; /**<BR>&nbsp;&nbsp;&nbsp;&nbsp; * 把]]&gt;替换为]]&amp;gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @param content 内容<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @return 格式化后的内容<BR>&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp; public static String formatRssCData(String content)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String result = StringFunc.replace(content,"\\]\\]&gt;","]]&amp;gt;");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return result;<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; /**<BR>&nbsp;&nbsp;&nbsp;&nbsp; * 格式化为xml需要的字符串<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @param field 内容<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @return 格式化后的串<BR>&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp; public static String formatString2XML(String field)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return StringFunc.str2TextXML(field);<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; public static String getNowDateTime()<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return formatRssDate(DateTime.getNowTimestamp());<BR>&nbsp;&nbsp;&nbsp; }<BR></TD></TR></TBODY></TABLE><BR></P>
<P>利用FreeMarker生成静态文件的代码如下:</P>
<P>
<TABLE class=code cellSpacing=1 cellPadding=1 width="80%" align=center border=0>
<TBODY>
<TR>
<TD>
<P>&nbsp;private Configuration freemarker_cfg = null;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp; protected Configuration getFreeMarkerCFG()<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (null == freemarker_cfg)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Initialize the FreeMarker configuration;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // - Create a configuration instance<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; freemarker_cfg = new Configuration();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; freemarker_cfg.setClassForTemplateLoading(this.getClass(), "/htmlskin");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; freemarker_cfg.setDefaultEncoding("GBK");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return freemarker_cfg;<BR>&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; public boolean geneFileByFreeMarker(String templateFileName, Map propMap, String filePath,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String fileName, String encode)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Template t = getFreeMarkerCFG().getTemplate(templateFileName);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File afile = new File(filePath + "/" + fileName);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(afile),<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; encode));</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; propMap.put("baseurl", PropSet.getStringProp("url.root"));</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; t.process(propMap, out);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch (TemplateException e)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LogMan.error("Error while processing FreeMarker template " + templateFileName, e);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch (IOException e)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LogMan.error("Error while generate File " + fileName, e);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;<BR>&nbsp;&nbsp;&nbsp; }<BR></P></TD></TR></TBODY></TABLE><BR></P>
<P>新闻系统中调用重新生成RSS文件的代码如下:</P>
<P>
<TABLE class=code cellSpacing=1 cellPadding=1 width="80%" align=center border=0>
<TBODY>
<TR>
<TD>
<P>&nbsp;&nbsp;&nbsp; /**<BR>&nbsp;&nbsp;&nbsp;&nbsp; * 重新生成RSS文件.<BR>&nbsp;&nbsp;&nbsp;&nbsp; * <BR>&nbsp;&nbsp;&nbsp;&nbsp; * @param nid 更新的新闻的id,如果不包含在最新的新闻里,则不更新RSS.nid &lt;1则更新<BR>&nbsp;&nbsp;&nbsp;&nbsp; * <BR>&nbsp;&nbsp;&nbsp;&nbsp; * @return 是否成功<BR>&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp; private boolean renewRSS(int nid)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; List newsList = 装载新闻的代码</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boolean shouldUpdate = false;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (nid &gt; 0)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; newsList.size(); i++)<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; NewsItem aNews = (NewsItem) newsList.get(i);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (aNews.getNid() == nid)<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;&nbsp;&nbsp;&nbsp;&nbsp; shouldUpdate = true;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<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; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; shouldUpdate = true;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //不更新,则返回<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!shouldUpdate)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Map root = new HashMap();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; root.put("rssutil",new RSSUtil());</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; root.put("newslist", newsList);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; root.put("now",DateTime.getNowTimestamp());</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; geneFileByFreeMarker("/news/rss.ftl", root, PropSet.getStringProp("rss.rssdir"), PropSet<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .getStringProp("rss.rssfile"), "UTF-8");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;<BR>&nbsp;&nbsp;&nbsp; }<BR></P></TD></TR></TBODY></TABLE><BR><BR>在增加或者更新/删除新闻的地方需要调用这个renewRSS函数.</P>
<P>(二)JSP动态方式</P>
<P>相对静态方式而言,简单的多,不过效率上可能就不太好了.</P>
<P>webwork2的Action代码如下:</P>
<P>
<TABLE class=code cellSpacing=1 cellPadding=1 width="80%" align=center border=0>
<TBODY>
<TR>
<TD>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; newsList =&nbsp;装载新闻代码<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return SUCCESS;&nbsp;</P></TD></TR></TBODY></TABLE><BR></P>
<P>视图Jsp如下:</P>
<P>
<TABLE class=code cellSpacing=1 cellPadding=1 width="80%" align=center border=0>
<TBODY>
<TR>
<TD><BR>&lt;%@ page contentType="text/xml; charset=UTF-8"%&gt;<BR>&lt;%@ taglib uri="jscud" prefix="jscud" %&gt;<BR>&lt;%@ taglib uri="webwork" prefix="ww" %&gt;<BR>&lt;ww:bean name="’com.jscud.www.util.RSSUtil’" id="rssUtil" /&gt;<BR>&lt;?xml version="1.0" encoding="UTF-8" ?&gt; <BR>&nbsp;&lt;rss version="2.0"&gt;<BR>&nbsp;&lt;channel&gt;<BR>&nbsp; &lt;title&gt;JScud Develop&lt;/title&gt; <BR>&nbsp; &lt;link&gt;http://www.jscud.com/&lt;/link&gt; <BR>&nbsp; &lt;language&gt;zh-cn&lt;/language&gt; <BR>&nbsp; &lt;description &gt;JScud Develop By Scud&lt;/description&gt;<BR>&nbsp; &lt;webMaster&gt;xxx@21cn.com(scud)&lt;/webMaster&gt; <BR>&nbsp; &lt;lastBuildDate&gt;&lt;ww:property value="#rssUtil.nowDateTime" /&gt;&lt;/lastBuildDate&gt; <BR>&nbsp; &nbsp;<BR>&nbsp; &nbsp;&lt;ww:iterator value="newsList"&gt;<BR>&nbsp; &lt;item&gt;<BR>&nbsp;&nbsp; &lt;title&gt;&lt;ww:property value="#rssUtil.formatString2XML(title)"/&gt;&lt;/title&gt;<BR>&nbsp;&nbsp; &lt;link&gt;http://www.jscud.com/srun/news/viewhtml/&lt;ww:property&nbsp; value="htmlFilePath" /&gt;/&lt;ww:property&nbsp; value="nid" /&gt;.htm&lt;/link&gt; <BR>&nbsp;&nbsp; &lt;pubDate&gt;&lt;ww:property&nbsp; value="#rssUtil.formatRssDate(addtime)" /&gt;&lt;/pubDate&gt; <BR>&nbsp;&nbsp; &lt;description&gt;&lt;![CDATA[<BR>&nbsp;&nbsp;&lt;ww:property value="#rssUtil.formatRssCData(showContent)"/&gt;<BR>&nbsp;&nbsp; ]]&gt;<BR>&nbsp;&nbsp; &lt;/description&gt;<BR>&nbsp;&nbsp; &lt;/item&gt;<BR>&nbsp;&lt;/ww:iterator&gt;<BR>&nbsp; &lt;/channel&gt;<BR>&nbsp;&lt;/rss&gt;</TD></TR></TBODY></TABLE><BR></P>
<P>jsp的方式简单多了,上面的jsp里面还演示了ww:bean的使用 :)</P>
<P><BR>上面的类里面引用了很多其他的工具类,这里不一一列出,可以自己实现它们,都是很简单的类. :)<BR></P><img src ="http://www.blogjava.net/scud/aggbug/10510.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/scud/" target="_blank">Scud(飞云小侠)</a> 2005-08-19 14:11 <a href="http://www.blogjava.net/scud/archive/2005/08/19/10510.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Rss 中日期格式的研究</title><link>http://www.blogjava.net/scud/archive/2005/08/17/10370.html</link><dc:creator>Scud(飞云小侠)</dc:creator><author>Scud(飞云小侠)</author><pubDate>Wed, 17 Aug 2005 10:11:00 GMT</pubDate><guid>http://www.blogjava.net/scud/archive/2005/08/17/10370.html</guid><wfw:comment>http://www.blogjava.net/scud/comments/10370.html</wfw:comment><comments>http://www.blogjava.net/scud/archive/2005/08/17/10370.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/scud/comments/commentRss/10370.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/scud/services/trackbacks/10370.html</trackback:ping><description><![CDATA[<P>scud(飞云小侠) <A href="http://www.jscud.com">http://www.jscud.com</A> 转载请注明来源/作者</P>
<P>&nbsp;</P>
<P>rss中日期格式要求遵守rfc822规范,其中是这么写的:</P>
<P><PRE>     date-time   =  [ day "," ] date time        ; dd mm yy
                                                 ;  hh:mm:ss zzz

     day         =  "Mon"  / "Tue" /  "Wed"  / "Thu"
                 /  "Fri"  / "Sat" /  "Sun"

     date        =  1*2DIGIT month 2DIGIT        ; day month year
                                                 ;  e.g. 20 Jun 82

     month       =  "Jan"  /  "Feb" /  "Mar"  /  "Apr"
                 /  "May"  /  "Jun" /  "Jul"  /  "Aug"
                 /  "Sep"  /  "Oct" /  "Nov"  /  "Dec"

     time        =  hour zone                    ; ANSI and Military

     hour        =  2DIGIT ":" 2DIGIT [":" 2DIGIT]
                                                 ; 00:00:00 - 23:59:59

     zone        =  "UT"  / "GMT"                ; Universal Time
                                                 ; North American : UT
                 /  "EST" / "EDT"                ;  Eastern:  - 5/ - 4
                 /  "CST" / "CDT"                ;  Central:  - 6/ - 5
                 /  "MST" / "MDT"                ;  Mountain: - 7/ - 6
                 /  "PST" / "PDT"                ;  Pacific:  - 8/ - 7
                 /  1ALPHA                       ; Military: Z = UT;
                                                 ;  A:-1; (J not used)
                                                 ;  M:-12; N:+1; Y:+12
                 / ( ("+" / "-") 4DIGIT )        ; Local differential
                                                 ;  hours+min. (HHMM)
</PRE>
<P></P>
<P>&nbsp;</P>
<P><BR><BR>可以看出,前面的星期X是可以省略的,后面的时间是要求有时区的.</P>
<DD>
<P>示例如下(以在中国的中文操作系统机器为例):</P>
<P><BR><FONT color=#0000ff>&nbsp;1.Tue, 16 Aug 2005 15:33:33 GMT<BR>&nbsp;2.Tue, 16 Aug 2005 23:33:33 +0800</FONT></P>
<P>其实这个rfc822应该也是电子邮件内容格式的规范,找一个邮件看看内容,也可以看出,邮件的时间格式也是遵循这个规范的.</P>
<P>要输入第一种格式,使用SimpleDateFormat格式化即可,代码如下</P>
<P>
<TABLE class=code cellSpacing=1 cellPadding=1 width="80%" align=center border=0>
<TBODY>
<TR>
<TD>&nbsp;&nbsp;&nbsp; public static void test1(Date date)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SimpleDateFormat sdfTemp = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z",Locale.US);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SimpleTimeZone aZone = new SimpleTimeZone(8,"GMT");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sdfTemp.setTimeZone(aZone);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(sdfTemp.format(date));&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; }&nbsp;</TD></TR></TBODY></TABLE><BR>注意,其中设置了时区为GMT,否则会输出:</P>
<P>&nbsp;<FONT color=#ff0000>Tue, 16 Aug 2005 23:33:33 CST</FONT></P>
<P>这里的CST意思是代表"中国时间",但是一经搜索,发现CST代表了好几个时区,太让人混乱了.而在RTF822里面,CST仅代表美国中部时间.所以如果使用SimpleDateFormat,要设置时区以GMT表示,否则容易让人迷惑而且不知道是那个时区.</P>
<P><FONT color=#ff0000>假设你在中国,想根据当地时间输入复合当地时间的字符串,让人一看就能明白文章的日期,那么就使用第二种格式</FONT>.(我推荐使用第二种方式,当然你的频道主要给外国朋友浏览登除外)</P>
<P>上面说到和邮件有关,于是我们看看JavaMail包里面的javax.mail.internet.MailDateFormat,可以用来格式化日期:<BR>(MyEclipse 3.8.4附带的J2EE 1.3中的JavaMail包)</P>
<P>
<TABLE class=code cellSpacing=1 cellPadding=1 width="80%" align=center border=0>
<TBODY>
<TR>
<TD>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MailDateFormat mdf = new MailDateFormat();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SimpleTimeZone aZone = new SimpleTimeZone(8,"GMT");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //mdf.setTimeZone(aZone);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(mdf.format(date));&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD></TR></TBODY></TABLE><BR></P>
<P>输出结果为:</P>
<P><FONT color=#0000ff>&nbsp;Tue, 16 Aug 2005 23:33:33 +0800 (CST)</FONT><BR>&nbsp;<BR>如果设置了时区为GMT,则输出:</P>
<P>&nbsp;<FONT color=#0000ff>Tue, 16 Aug 2005 15:33:33 +0000 (GMT)</FONT>&nbsp;<BR>&nbsp;<BR>&nbsp;<BR>&nbsp;<BR>可以看到相对RTF822而言,好像多了一个后面的时区的说明及其括号.不知道这到底是怎么回事? </P>
<P>在硬盘上查找一番,发现在JIRA程序和Confluence中的RSS里都使用了这个日期格式.&nbsp;</P>
<P>注意到这个不同,我浏览了一下outlook Express里面的邮件,发现两种时间格式的邮件都存在,真是让人迷惑,或许都可以吧,呵呵 :)</P>
<P>如果不想使用MailDateFormat的格式,那么就自己写一个类来实现吧,例如</P>
<P>
<TABLE class=code cellSpacing=1 cellPadding=1 width="80%" align=center border=0>
<TBODY>
<TR>
<TD>&nbsp;public class RssDateFormat extends MailDateFormat<BR>&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp; public RssDateFormat()<BR>&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; applyPattern("EEE, d MMM yyyy HH:mm:ss ’XXXXX’");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;<BR>&nbsp;}&nbsp;</TD></TR></TBODY></TABLE><BR>&nbsp;<BR>这是最简单的了,当然可以把MailDateFormat的源码拿过来改改更好一点,还不用依赖JavaMail了. :)</P>
<P>至此,我的RSS中的日期终于正确而且让我满意了. :)</P>
<P>&nbsp;</P>
<P><BR>&nbsp;</P></DD><img src ="http://www.blogjava.net/scud/aggbug/10370.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/scud/" target="_blank">Scud(飞云小侠)</a> 2005-08-17 18:11 <a href="http://www.blogjava.net/scud/archive/2005/08/17/10370.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用Lucene进行全文检索(三)---进行搜索</title><link>http://www.blogjava.net/scud/archive/2005/08/12/9981.html</link><dc:creator>Scud(飞云小侠)</dc:creator><author>Scud(飞云小侠)</author><pubDate>Fri, 12 Aug 2005 09:34:00 GMT</pubDate><guid>http://www.blogjava.net/scud/archive/2005/08/12/9981.html</guid><wfw:comment>http://www.blogjava.net/scud/comments/9981.html</wfw:comment><comments>http://www.blogjava.net/scud/archive/2005/08/12/9981.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/scud/comments/commentRss/9981.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/scud/services/trackbacks/9981.html</trackback:ping><description><![CDATA[<P>scud(飞云小侠) <A href="http://www.jscud.com/"><FONT color=#002c99>http://www.jscud.com</FONT></A> 转载请注明来源/作者</P>
<P>关键字:lucene,html parser,全文检索,IndexReader,Document,Field,IndexWriter,Term,HTMLPAGE</P>
<P><BR>&nbsp;无论是建立索引还是分析内容,都是为了用户的搜索服务.<BR>&nbsp;<BR>&nbsp;在Lucene中,如果需要使用搜索,需要使用Searcher类,这是一个抽象类,它有2个子类:IndexSearcher和MultiSearcher.<BR>&nbsp;<BR>&nbsp;IndexSearcher是对一个索引进行搜索,如果你需要对多个索引进行搜索,可以使用MultiSearcher.下面的内容只介绍了IndexSearcher.<BR>&nbsp;<BR>&nbsp;搜索涉及到几个问题:分页,组合条件,根据条件过滤,排序等等.<BR>&nbsp;<BR>&nbsp;分页:分页在记录列表的地方都会遇到,这里不在赘述,我也实现过一个保存分页结果和显示结果的类,用于自己的实际工作,下面也会用到保存分页结果的类,代码如下:</P>
<P>
<TABLE class=code cellSpacing=1 cellPadding=1 width="80%" align=center border=0>
<TBODY>
<TR>
<TD>&nbsp;&nbsp;package com.jscud.support;<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;/**<BR>&nbsp;&nbsp; * 分页显示用的参数.<BR>&nbsp;&nbsp; * <BR>&nbsp;&nbsp; * @author scud(飞云小侠) <A href="http://www.jscud.com/"><FONT color=#002c99>http://www.jscud.com</FONT></A><BR>&nbsp;&nbsp; *&nbsp; <BR>&nbsp;&nbsp; */<BR>&nbsp;&nbsp; <BR>&nbsp;&nbsp;public class DivPageInfo<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //开始记录数<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private int recStart;<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //结束记录数<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private int recEnd;<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //总页数<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private int pageCount;<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //当前页<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private int page;<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //记录总数<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private int recCount;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //每页记录数<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private int perPageRows;<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public int getNicePageCount()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return getNicePageNum(pageCount);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //get,set等,不在列出<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //......<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * 得到友好的页数数字,页数为0时,返回1.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @return 得到友好的页数<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static int getNicePageNum(int nPage)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (nPage == 0)<BR>&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 1;<BR>&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; else<BR>&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return nPage;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;}&nbsp;<BR></TD></TR></TBODY></TABLE><BR></P>
<P>&nbsp;显示分页结果的类就需要大家根据自己使用的框架来具体实现了.我使用的是WebWork.<BR>&nbsp;<BR>&nbsp;组合条件:在Lucene中,搜索的条件可以组合的很复杂,相关的类有BooleanQuery, FilteredQuery, MultiTermQuery, PhrasePrefixQuery, PhraseQuery, PrefixQuery, RangeQuery, SpanQuery, TermQuery 等等,从而可以组合出很复杂的条件用于查询.<BR>&nbsp;另外QueryParser可以根据用户输入的字符串和设定的解析器和字段设置等,可以自动产生新的组合条件用于查询,例如用户输入"john AND black",QueryParser可以自己分析出用户是需要查询字段中同时包含"john"和"black"的结果.<BR>&nbsp;<BR>&nbsp;过滤条件:有时候根据具体的用户需求,有些记录对于一些用户是不可见的,此时就要使用过滤器来防止不合法的用户看到不应该看到的记录.过滤器同时也可以根据一些具体的条件来过滤掉一些用户不想看到的记录.如果需要实现自己的filter,只要参考QueryFilter,DateFilter实现Filter即可.<BR>&nbsp;<BR>&nbsp;排序:有时候,可能需要根据某个字段进行排序,例如按照时间排序.当然更多的时候是按照搜索结果的符合度进行排序,lucene默认的排序就是按照符合度来进行排序的.<BR>&nbsp;<BR>&nbsp;进行搜索的代码如下,根据自己的需要进行代码的修改:<BR>&nbsp;<BR></P>
<P>
<TABLE class=code cellSpacing=1 cellPadding=1 width="80%" align=center border=0>
<TBODY>
<TR>
<TD>&nbsp;/**<BR>&nbsp;* 进行搜索.<BR>&nbsp;*<BR>&nbsp;* 参数依次为:搜索内容(支持lucene语法),当前页,每页记录数,分页信息对象<BR>&nbsp;*<BR>&nbsp;*/<BR>&nbsp;&nbsp;&nbsp; public static List search(String searchText, int page, int perpage, final DivPageInfo pageinfo)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; List docs = new ArrayList();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(!LuceneSearch.indexExist(indexDir)) { return docs; } 
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Searcher searcher = null;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StandardAnalyzer analyzer = new StandardAnalyzer();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //处理检索条件<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Query titleQuery = QueryParser.parse(searchText, "title", analyzer);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Query contextQuery = QueryParser.parse(searchText, "content", analyzer);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Query otherQuery = QueryParser.parse(searchText, "other", analyzer);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BooleanQuery query = new BooleanQuery();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; query.add(titleQuery, false, false);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; query.add(contextQuery, false, false);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; query.add(otherQuery, false, false);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //分页检索<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; searcher = new IndexSearcher(indexDir);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Hits hits = searcher.search(query);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DivPageInfo.divPage(hits.length(), perpage, page, pageinfo);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //取出当前页的记录<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = pageinfo.getRecStart(); i &lt;= pageinfo.getRecEnd(); i++)<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; docs.add(LuceneDocument.getDocument(hits.doc(i - 1)));<BR>&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; catch (IOException e)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LogMan.error("Error occur When Search Lucene", e);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch (ParseException e)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LogMan.error("Error occur When Search Lucene", e);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; finally<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<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; if (null != searcher)<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;&nbsp;&nbsp;&nbsp;&nbsp; searcher.close();<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; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch (IOException e)<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; LogMan.warn("Close searcher Error");<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 docs;<BR>&nbsp;&nbsp;&nbsp; }<BR></P></TD></TR></TBODY></TABLE></P>
<P><BR><BR>&nbsp;<BR>&nbsp;代码中出现了一个新的类Hits,Hits是lucene的搜索结果集,是lazy load的结果集,只有你真正访问它,它才去装载真正的数据.<BR>&nbsp;<BR>&nbsp;代码中还出现了一个LuceneDocument,这是为了在页面中显示而写的一个辅助类,因为lucene的Document是final的,无法进行扩展,而要显示时间字段必须要调用DateField中的函数,这样在页面中显示就不太直观了,所以写了这个辅助类,代码如下:<BR>&nbsp;<BR></P>
<P>
<TABLE class=code cellSpacing=1 cellPadding=1 width="80%" align=center border=0>
<TBODY>
<TR>
<TD>&nbsp;&nbsp;package com.jscud.www.support.search;<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;import java.sql.Timestamp;<BR>&nbsp;&nbsp;import java.util.Date;<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;import org.apache.lucene.document.DateField;<BR>&nbsp;&nbsp;import org.apache.lucene.document.Document;<BR>&nbsp;&nbsp;import org.apache.lucene.document.Field;<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;/**<BR>&nbsp;&nbsp; * 对Lucene的Document的封装,用于显示目的. <BR>&nbsp;&nbsp; *<BR>&nbsp;&nbsp; * @author scud(飞云小侠) <A href="http://www.jscud.com/"><FONT color=#002c99>http://www.jscud.com</FONT></A><BR>&nbsp;&nbsp; *<BR>&nbsp;&nbsp; */<BR>&nbsp;&nbsp;public class LuceneDocument<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private Document doc;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public LuceneDocument(Document doc)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.doc = doc;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static LuceneDocument getDocument(Document doc)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new LuceneDocument(doc);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String getValue(String name)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return doc.get(name);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Field getField(String name)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return doc.getField(name);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Timestamp getDateTime(String name)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String value = doc.get(name);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new Timestamp( DateField.stringToTime(value));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Date getDate(String name)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String value = doc.get(name);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return&nbsp; DateField.stringToDate(value);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;}<BR></TD></TR></TBODY></TABLE></P>
<P><BR>&nbsp;<BR>&nbsp;使用WebWork对结果集进行了显示,代码如下:</P>
<P>
<TABLE class=code cellSpacing=1 cellPadding=1 width="80%" align=center border=0>
<TBODY>
<TR>
<TD>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ww:iterator value="docs"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;tr &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;td&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;a href="&lt;jscud:contextpath /&gt;&lt;ww:property&nbsp; value="getValue('visiturl')" /&gt;"&nbsp; target="_blank" &gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ww:property value="getValue('title')" escape="true" /&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/a&gt; &amp;nbsp; (&lt;jscud:datetime value="getDateTime('addtime')" /&gt;)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/td&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/tr&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/ww:iterator&gt;&nbsp;<BR>&nbsp;&nbsp;</TD></TR></TBODY></TABLE><BR><BR><BR>&nbsp;然后调用分页信息显示tag即可.<BR>&nbsp;<BR>&nbsp;<BR>&nbsp;通过以上的应用,可以看到,其实使用lucene很简单,以前总觉得很神秘,所以一直没有使用过,用过之后才觉得如此简单.<BR>&nbsp;<BR>&nbsp;<BR>&nbsp;当然,对于大容量数据下,群集情况下,在网上都有很多解决方案,在此不一一提出,感兴趣的读者可以自己去搜索. :)<BR>&nbsp;<BR></P><img src ="http://www.blogjava.net/scud/aggbug/9981.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/scud/" target="_blank">Scud(飞云小侠)</a> 2005-08-12 17:34 <a href="http://www.blogjava.net/scud/archive/2005/08/12/9981.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用Lucene进行全文检索(二)---得到有效的内容</title><link>http://www.blogjava.net/scud/archive/2005/08/12/9980.html</link><dc:creator>Scud(飞云小侠)</dc:creator><author>Scud(飞云小侠)</author><pubDate>Fri, 12 Aug 2005 09:33:00 GMT</pubDate><guid>http://www.blogjava.net/scud/archive/2005/08/12/9980.html</guid><wfw:comment>http://www.blogjava.net/scud/comments/9980.html</wfw:comment><comments>http://www.blogjava.net/scud/archive/2005/08/12/9980.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/scud/comments/commentRss/9980.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/scud/services/trackbacks/9980.html</trackback:ping><description><![CDATA[<STRONG>
<P>scud(飞云小侠) <A href="http://www.jscud.com/"><FONT color=#002c99>http://www.jscud.com</FONT></A> 转载请注明来源/作者</P>
<P>关键字:lucene,html parser,全文检索,IndexReader,Document,Field,IndexWriter,Term,HTMLPAGE</P>
<P><BR>&nbsp; 在使用lucene对相关内容进行索引时,会遇到各种格式的内容,例如Html,PDF,Word等等,那么我们如何从这么文档中得到我们需要的内容哪?例如Html的内容,一般我们不需要对Html标签建立索引,因为那不是我们需要搜索的内容.这个时候,我们就需要从Html内容中解析出我们所需要的内容.对于PDF,Word文档,也是类似的要求.<BR>&nbsp; <BR>&nbsp; 总之,我们只需要从内容中提取出我们需要的文本来建立索引,这样用户就能搜索到需要的内容,然后访问对应的资源即可.</P>
<P>&nbsp; Lucene本身带的例子中有一个解析Html的代码,不过不是纯JAVA的,所以在网上我又找到了另外一个Html解析器,网址如下:http://htmlparser.sourceforge.net.<BR>&nbsp; <BR>&nbsp; 对PDF解析的相关项目有很多,例如PDFBox.在PDFBox里面提出pdf的文本内容只需要一句话即可:&nbsp;&nbsp;<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp; 
<TABLE class=code cellSpacing=1 cellPadding=1 width="80%" align=center border=0>
<TBODY>
<TR>
<TD>Document doc = LucenePDFDocument.getDocument( file );&nbsp;&nbsp;</TD></TR></TBODY></TABLE><BR>&nbsp;&nbsp;<BR>&nbsp; 当然如果需要更高级的设置,就要使用PDFBox中PDFTextStripper等类来实现更高级的操作了.<BR>&nbsp; <BR>&nbsp; <BR>&nbsp; 对Word文档解析的相关有POI,网址是 <A href="http://jakarta.apache.org/poi/"><FONT color=#002c99>http://jakarta.apache.org/poi/</FONT></A>.<BR>&nbsp; <BR>&nbsp; HtmlParser本身提供的功能很强大,我们下面主要来关注我们需要的功能.首先给出几个函数如下:<BR>&nbsp; <BR>
<TABLE class=code cellSpacing=1 cellPadding=1 width="80%" align=center border=0>
<TBODY>
<TR>
<TD>
<P>&nbsp;/**<BR>&nbsp;* 解析一个Html页面,返回一个Html页面类.<BR>&nbsp;*<BR>&nbsp;* @param resource 文件路径或者网址<BR>&nbsp;*/<BR>&nbsp;&nbsp;&nbsp; public static SearchHtmlPage parseHtmlPage(String resource)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String title = "";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String body = "";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Parser myParser = new Parser(resource);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //设置编码:根据实际情况修改<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myParser.setEncoding("GBK");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HtmlPage visitor = new HtmlPage(myParser);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myParser.visitAllNodesWith(visitor);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; title = visitor.getTitle();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; body = combineNodeText(visitor.getBody().toNodeArray());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch (ParserException e)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LogMan.error("Parse Html Page " + resource + " Error!");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SearchHtmlPage result = new SearchHtmlPage(title, body);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return result;<BR>&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; /**<BR>&nbsp;&nbsp;&nbsp;&nbsp; * 解析Html内容,得到普通文本和链接的内容.<BR>&nbsp;&nbsp;&nbsp;&nbsp; * <BR>&nbsp;&nbsp;&nbsp;&nbsp; * @param content 要解析的内容<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @return 返回解析后的内容<BR>&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp; public static String parseHtmlContent(String content)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Parser myParser;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NodeList nodeList = null;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myParser = Parser.createParser(content, "GBK");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NodeFilter textFilter = new NodeClassFilter(TextNode.class);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NodeFilter linkFilter = new NodeClassFilter(LinkTag.class);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //暂时不处理 meta<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //NodeFilter metaFilter = new NodeClassFilter(MetaTag.class);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OrFilter lastFilter = new OrFilter();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lastFilter.setPredicates(new NodeFilter[] { textFilter, linkFilter });</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nodeList = myParser.parse(lastFilter);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch (ParserException e)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LogMan.warn("Parse Content Error", e);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //中场退出了<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (null == nodeList)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return "";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Node[] nodes = nodeList.toNodeArray();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String result = combineNodeText(nodes);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return result;<BR>&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;//合并节点的有效内容<BR>&nbsp;&nbsp;&nbsp; private static String combineNodeText(Node[] nodes)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StringBuffer result = new StringBuffer();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; nodes.length; i++)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Node anode = (Node) nodes[i];</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String line = "";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (anode instanceof TextNode)<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; TextNode textnode = (TextNode) anode;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //line = textnode.toPlainTextString().trim();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line = textnode.getText();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if (anode instanceof LinkTag)<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; LinkTag linknode = (LinkTag) anode;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line = linknode.getLink();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //过滤jsp标签<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line = StringFunc.replace(line, "&lt;%.*%&gt;", "");<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; if (StringFunc.isTrimEmpty(line)) continue;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result.append(" ").append(line);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return result.toString();<BR>&nbsp;&nbsp;&nbsp; }</P></TD></TR></TBODY></TABLE><BR>&nbsp;&nbsp;<BR>&nbsp; 其中SearchHtmlPage类是表示一个Html页面的模型,包含标题和内容,代码如下:<BR>&nbsp;&nbsp;<BR>
<TABLE class=code cellSpacing=1 cellPadding=1 width="80%" align=center border=0>
<TBODY>
<TR>
<TD>&nbsp;package com.jscud.www.support.search;<BR>&nbsp;<BR>&nbsp;/**<BR>&nbsp; * 搜索时解析Html后返回的页面模型.<BR>&nbsp; * <BR>&nbsp; * @author scud(飞云小侠) <A href="http://www.jscud.com/"><FONT color=#002c99>http://www.jscud.com</FONT></A><BR>&nbsp; *&nbsp; <BR>&nbsp; */<BR>&nbsp;public class SearchHtmlPage<BR>&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp; /**标题*/<BR>&nbsp;&nbsp;&nbsp;&nbsp; private String title;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp; /**内容*/<BR>&nbsp;&nbsp;&nbsp;&nbsp; private String body;<BR>&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp; public SearchHtmlPage(String title, String body)<BR>&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.title = title;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.body = body;<BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp; public String getBody()<BR>&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return body;<BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp; public void setBody(String body)<BR>&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.body = body;<BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp; public String getTitle()<BR>&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return title;<BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp; public void setTitle(String title)<BR>&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.title = title;<BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;}<BR>&nbsp; </TD></TR></TBODY></TABLE><BR><BR>&nbsp;<BR>&nbsp; 当然,使用HtmlParser解析Html资源还有很多其他的方法,可以设置很多的条件来满足用户的解析要求,用户可以阅读其他的文章或者HtmlParser的文档来了解,在此不多介绍.<BR>&nbsp; <BR>&nbsp; 下一节讲解如何进行搜索.</P>
<P>&nbsp;</P></STRONG><img src ="http://www.blogjava.net/scud/aggbug/9980.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/scud/" target="_blank">Scud(飞云小侠)</a> 2005-08-12 17:33 <a href="http://www.blogjava.net/scud/archive/2005/08/12/9980.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用Lucene进行全文检索(一)---处理索引</title><link>http://www.blogjava.net/scud/archive/2005/08/12/9979.html</link><dc:creator>Scud(飞云小侠)</dc:creator><author>Scud(飞云小侠)</author><pubDate>Fri, 12 Aug 2005 09:31:00 GMT</pubDate><guid>http://www.blogjava.net/scud/archive/2005/08/12/9979.html</guid><wfw:comment>http://www.blogjava.net/scud/comments/9979.html</wfw:comment><comments>http://www.blogjava.net/scud/archive/2005/08/12/9979.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/scud/comments/commentRss/9979.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/scud/services/trackbacks/9979.html</trackback:ping><description><![CDATA[<P>scud(飞云小侠) <A href="http://www.jscud.com/">http://www.jscud.com</A> 转载请注明来源/作者</P>
<P>关键字:lucene,html parser,全文检索,IndexReader,Document,Field,IndexWriter,Term,HTMLPAGE</P>
<P><BR>&nbsp;Lucene是一个全文检索的引擎,目前有Java和.Net 等几个版本.Java版本的网址是<A href="http://lucene.apache.org/">http://lucene.apache.org</A>.相关的一个项目是车东的WebLucene: <A href="http://sourceforge.net/projects/weblucene">http://sourceforge.net/projects/weblucene</A>.</P>
<P>&nbsp;首先,基于一个简单的新闻系统,要想做全文检索.新闻系统的管理等在这里不在具体提出,下面列出新闻对象的类:<BR>&nbsp;<BR>&nbsp;注:程序用会到一些工具类,不在此列出,用户可以自己实现.<BR>&nbsp;<BR>&nbsp;</P>
<P>
<TABLE class=code cellSpacing=1 cellPadding=1 width="80%" align=center border=0>
<TBODY>
<TR>
<TD>&nbsp;&nbsp;package com.jscud.website.newsinfo.bean;<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;import java.sql.Timestamp;<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;import com.jscud.util.DateTime;<BR>&nbsp;&nbsp;import com.jscud.util.StringFunc;<BR>&nbsp;&nbsp;import com.jscud.website.newsinfo.NewsConst;<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;/**<BR>&nbsp;&nbsp; * 一个新闻.<BR>&nbsp;&nbsp; * <BR>&nbsp;&nbsp; * @author scud(飞云小侠) <A href="http://www.jscud.com/">http://www.jscud.com</A><BR>&nbsp;&nbsp; *&nbsp; <BR>&nbsp;&nbsp; */<BR>&nbsp;&nbsp;public class NewsItem<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private int nid; //新闻编号<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private int cid; //类别编号<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private String title;//标题<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private int showtype; //内容类型:目前支持url和html<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private String content;//内容<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private String url;//对应网址,如果内容类型是url的话<BR>&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private Timestamp addtime; //增加时间<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private int click; //点击数<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //对应的get,set函数,较多不在列出,可以使用工具生成<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //......<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * 按照类型格式化<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String getShowContent()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String sRes = content;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(showtype == NewsConst.ShowType_HTML)<BR>&nbsp;&nbsp;&nbsp;&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;&nbsp;&nbsp;&nbsp; return sRes;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String getTarget()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(showtype == NewsConst.ShowType_URL)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return "_blank";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return "";&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * 静态Html文件的路径及其名字<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String getHtmlFileName()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int nYear = DateTime.getYear_Date(getAddtime());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int nMonth =&nbsp; DateTime.getMonth_Date(getAddtime());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String sGeneFileName = <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;"/news/" + getCid() + "/" + nYear + "/" + nMonth +"/" + getNid() + ".htm";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return sGeneFileName;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * 静态Html文件的路径<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String getHtmlFilePath()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int nYear = DateTime.getYear_Date(getAddtime());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int nMonth =&nbsp; DateTime.getMonth_Date(getAddtime());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String sGeneFilePath = <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;getCid() + "_" + nYear + "_" + nMonth;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return sGeneFilePath;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;}&nbsp;<BR></TD></TR></TBODY></TABLE></P>
<P><BR>&nbsp;<BR>&nbsp;可以看到,我们需要对标题和内容进行检索,为了这个目的,我们首先需要来研究一下lucene.<BR>&nbsp;<BR>&nbsp;在Lucene中,如果要进行全文检索,必须要先建立索引然后才能进行检索,当然实际工作中还会有删除索引和更新索引的工作.<BR>&nbsp;<BR>&nbsp;在此之前,介绍一个最基本的类(摘抄自<A href="http://www.blogjava.net/cap/archive/2005/07/17/7849.html">http://www.blogjava.net/cap/archive/2005/07/17/7849.html</A>):<BR>&nbsp;<BR>&nbsp;Analyzer 文件的分析器（听起来别扭，还是叫Analyzer好了)的抽象，这个类用来处理分词(对中文尤其重要，转换大小写(Computer-&gt;computer,实现查询大小写无关)，转换词根(computers-&gt;computer),消除stop words等,还负责把其他格式文档转换为纯文本等.<BR>&nbsp;<BR>&nbsp;在lucene中,一般会使用StandardAnalyzer来分析内容,它支持中文等多字节语言,当然可以自己实现特殊的解析器.StandardAnalyzer目前对中文的处理是按照单字来处理的,这是最简单的办法,但是也有缺点,会组合出一些没有意义的结果来.&nbsp;<BR>&nbsp;<BR>&nbsp;<BR>&nbsp;首先我们来了解建立索引,建立索引包含2种情况,一种是给一条新闻建立索引,另外的情况是在开始或者一定的时间给批量的新闻建立索引,所以为了通用,我们写一个通用的建立索引的函数:<BR>&nbsp;<BR>&nbsp;(一般一类的索引都放在一个目录下,这个配置可以在函数中定义,也可以写在配置文件中,通过参数传递给函数.)<BR></P>
<P>
<TABLE class=code cellSpacing=1 cellPadding=1 width="80%" align=center border=0>
<TBODY>
<TR>
<TD>&nbsp;&nbsp;&nbsp; /**<BR>&nbsp;&nbsp;&nbsp;&nbsp; * 生成索引.<BR>&nbsp;&nbsp;&nbsp;&nbsp; * <BR>&nbsp;&nbsp;&nbsp;&nbsp; * @param doc 目标文档<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @param indexDir 索引目录<BR>&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp; public static void makeIndex(Document doc, String indexDir)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; List aList = new ArrayList();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; aList.add(doc);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; makeIndex(aList, indexDir);<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp; /**<BR>&nbsp;&nbsp;&nbsp;&nbsp; * 生成索引.<BR>&nbsp;&nbsp;&nbsp;&nbsp; * <BR>&nbsp;&nbsp;&nbsp;&nbsp; * @param doc 生成的document.<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @param indexDir 索引目录<BR>&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp; public static void makeIndex(List docs, String indexDir)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (null == docs)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boolean indexExist = indexExist(indexDir); 
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IndexWriter writer = null;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StandardAnalyzer analyzer = new StandardAnalyzer();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //如果索引存在,就追加.如果不存在,就建立新的索引.lucene要是自动判决就好了.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(indexExist) <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; writer = new IndexWriter(indexDir, analyzer, false);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<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; writer = new IndexWriter(indexDir, analyzer, true);<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; //添加一条文档<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; docs.size(); i++)<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; Document doc = (Document) docs.get(i);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (null != doc)<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;&nbsp;&nbsp;&nbsp;&nbsp; writer.addDocument(doc);<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; }</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //索引完成后的处理<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; writer.optimize();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch (IOException e)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LogMan.warn("Error in Make Index", e);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; finally<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<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; if (null != writer)<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;&nbsp;&nbsp;&nbsp;&nbsp; writer.close();<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; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch (IOException e)<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; LogMan.warn("Close writer Error");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<BR></P></TD></TR></TBODY></TABLE></P>
<P><BR><BR>&nbsp;可以看到,建立索引用到类是IndexWrite,它可以新建索引或者追加索引,但是需要自己判断.判断是通过IndexReader这个类来实现的,函数如下:</P>
<P>&nbsp;</P>
<P>
<TABLE class=code cellSpacing=1 cellPadding=1 width="80%" align=center border=0>
<TBODY>
<TR>
<TD>&nbsp; /**<BR>&nbsp;&nbsp;&nbsp;&nbsp; * 检查索引是否存在.<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @param indexDir<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @return<BR>&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp; public static boolean indexExist(String indexDir)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return IndexReader.indexExists(indexDir);<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;</TD></TR></TBODY></TABLE></P>
<P><BR>&nbsp;如果每次都是新建索引的话,会把原来的记录删除,我在使用的时候一开始就没有注意到,后来观察了一下索引文件,才发现这个问题.<BR>&nbsp;<BR>&nbsp;<BR>&nbsp;还可以看到,建立索引是给用户的Document对象建立索引,Document表示索引中的一条文档记录.那么我们如何建立一个文档那?以新闻系统为例,代码如下:<BR>&nbsp;</P>
<P>
<TABLE class=code cellSpacing=1 cellPadding=1 width="80%" align=center border=0>
<TBODY>
<TR>
<TD>&nbsp;&nbsp;&nbsp;&nbsp; /**<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * 生成新闻的Document.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @param aNews 一条新闻.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @return lucene的文档对象<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp; public static Document makeNewsSearchDocument(NewsItem aNews)<BR>&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Document doc = new Document();<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; doc.add(Field.Keyword("nid", String.valueOf(aNews.getNid())));<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; doc.add(Field.Text("title", aNews.getTitle()));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //对Html进行解析,如果不是html,则不需要解析.或者根据格式调用自己的解析方法<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String content = parseHtmlContent(aNews.getContent());<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; doc.add(Field.UnStored("content", content));<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; doc.add(Field.Keyword("addtime", aNews.getAddtime()));<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //可以加入其他的内容:例如新闻的评论等<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; doc.add(Field.UnStored("other", ""));<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //访问url<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String newsUrl = "/srun/news/viewhtml/" + aNews.getHtmlFilePath() + "/" + aNews.getNid()<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; + ".htm";<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; doc.add(Field.UnIndexed("visiturl", newsUrl));<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return doc;<BR>&nbsp;&nbsp;&nbsp;&nbsp; }<BR></TD></TR></TBODY></TABLE></P>
<P><BR>&nbsp;<BR>&nbsp;通过上面的代码,我们把一条新闻转换为lucene的Document对象,从而进行索引工作.在上面的代码中,我们又引入了lucene中的Field(字段)类.Document文档就像数据库中的一条记录,它有很多字段,每个字段是一个Field对象.<BR>&nbsp;<BR>&nbsp;从别的文章摘抄一段关于Field的说明(摘抄自<A href="http://www.blogjava.net/cap/archive/2005/07/17/7849.html">http://www.blogjava.net/cap/archive/2005/07/17/7849.html</A>):<BR>&nbsp;[quote]<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; Analyzed Indexed Stored 说明 <BR>&nbsp;&nbsp;&nbsp; Field.Keyword(String,String/Date)&nbsp; N Y Y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这个Field用来储存会直接用来检索的比如(编号,姓名,日期等) <BR>&nbsp;&nbsp;&nbsp; Field.UnIndexed(String,String)&nbsp;&nbsp;&nbsp;&nbsp; N N Y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 不会用来检索的信息,但是检索后需要显示的,比如,硬件序列号,文档的url地址 <BR>&nbsp;&nbsp;&nbsp; Field.UnStored(String,String)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Y Y N&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 大段文本内容,会用来检索,但是检索后不需要从index中取内容,可以根据url去load真实的内容 <BR>&nbsp;&nbsp;&nbsp; Field.Text(String,String)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Y Y Y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 检索,获取都需要的内容,直接放index中,不过这样会增大index <BR>&nbsp;&nbsp;&nbsp; Field.Text(String,Reader)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Y Y N&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果是一个Reader, lucene猜测内容比较多,会采用Unstored的策略. <BR>&nbsp;[/quote]<BR>&nbsp;<BR>&nbsp;我们可以看到新闻的编号是直接用来检索的,所以是Keyword类型的字段,新闻的标题是需要检索和显示用的,所以是Text类型,而新闻的内容因为是Html格式的,所以在经过解析器的处理用,使用的UnStored的格式,而新闻的时间是直接用来检索的,所以是KeyWord类型.为了在新闻索引后用户可以访问到完整的新闻页面,还设置了一个UnIndexed类型的访问地址字段.<BR>&nbsp;<BR>&nbsp;(对Html进行解析的处理稍后在进行讲解)<BR>&nbsp;<BR>&nbsp;为一条新闻建立索引需要两个步骤:获取Document,传给makeIndex函数,代码如下:<BR></P>
<P>
<TABLE class=code cellSpacing=1 cellPadding=1 width="80%" align=center border=0>
<TBODY>
<TR>
<TD>&nbsp;&nbsp;&nbsp; public static void makeNewsInfoIndex(NewsItem aNews)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (null == aNews)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; makeIndex(makeNewsSearchDocument(aNews),indexDir);<BR>&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;</TD></TR></TBODY></TABLE></P>
<P><BR>&nbsp;<BR><BR>&nbsp;<BR>&nbsp;<BR>&nbsp;建立索引的工作就进行完了,只要在增加新闻后调用 makeNewsInfoIndex(newsitem); 就可以建立索引了.<BR>&nbsp;<BR>&nbsp;如果需要删除新闻,那么也要删除对应的索引,删除索引是通过IndexReader类来完成的:<BR>&nbsp;<BR></P>
<P>
<TABLE class=code cellSpacing=1 cellPadding=1 width="80%" align=center border=0>
<TBODY>
<TR>
<TD><BR>&nbsp;&nbsp;&nbsp; /**<BR>&nbsp;&nbsp;&nbsp;&nbsp; * 删除索引.<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @param aTerm 索引删除条件<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @param indexDir 索引目录<BR>&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp; public static void deleteIndex(Term aTerm, String indexDir)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; List aList = new ArrayList();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; aList.add(aTerm);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; deleteIndex(aList, indexDir);<BR>&nbsp;&nbsp;&nbsp; } 
<P>&nbsp;&nbsp;&nbsp; /**<BR>&nbsp;&nbsp;&nbsp;&nbsp; * 删除索引.<BR>&nbsp;&nbsp;&nbsp;&nbsp; * <BR>&nbsp;&nbsp;&nbsp;&nbsp; * @param aTerm 索引删除条件.<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @param indexDir 索引目录<BR>&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp; public static void deleteIndex(List terms, String indexDir)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (null == terms)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(!indexExist(indexDir)) { return; }</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IndexReader reader = null;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; reader = IndexReader.open(indexDir);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; terms.size(); i++)<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; Term aTerm = (Term) terms.get(i);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (null != aTerm)<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;&nbsp;&nbsp;&nbsp;&nbsp; reader.delete(aTerm);<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; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch (IOException e)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LogMan.warn("Error in Delete Index", e);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; finally<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<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; if (null != reader)<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;&nbsp;&nbsp;&nbsp;&nbsp; reader.close();<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; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch (IOException e)<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; LogMan.warn("Close reader Error");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }&nbsp;<BR></P></TD></TR></TBODY></TABLE></P>
<P><BR>&nbsp;<BR>&nbsp;删除索引需要一个条件,类似数据库中的字段条件,例如删除一条新闻的代码如下:<BR>&nbsp;<BR></P>
<P>
<TABLE class=code cellSpacing=1 cellPadding=1 width="80%" align=center border=0>
<TBODY>
<TR>
<TD>&nbsp;&nbsp;&nbsp;&nbsp; public static void deleteNewsInfoIndex(int nid)<BR>&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Term aTerm = new Term("nid", String.valueOf(nid));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; deleteIndex(aTerm,indexDir);<BR>&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;</TD></TR></TBODY></TABLE></P>
<P><BR><BR><BR>&nbsp;通过新闻的ID,就可以删除一条新闻.<BR>&nbsp;<BR>&nbsp;如果需要更新新闻,如何更新索引哪? 更新索引需要先删除索引然后新建索引2个步骤,其实就是把上面的代码组合起来,例如更新一条新闻:</P>
<P>
<TABLE class=code cellSpacing=1 cellPadding=1 width="80%" align=center border=0>
<TBODY>
<TR>
<TD>&nbsp;&nbsp;&nbsp;&nbsp; public static void updateNewsInfoIndex(NewsItem aNews)<BR>&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (null == aNews)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; deleteNewsInfoIndex(aNews.getNid());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; makeNewsInfoIndex(aNews);<BR>&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;<BR>&nbsp;</TD></TR></TBODY></TABLE></P>
<P><BR><BR>&nbsp;<BR>&nbsp;至此,索引的建立更新和删除就告一段落了.其中批量更新新闻的代码如下:<BR>&nbsp;(批量更新应该在访问人数少或者后台程序在夜间执行)</P>
<P>
<TABLE class=code cellSpacing=1 cellPadding=1 width="80%" align=center border=0>
<TBODY>
<TR>
<TD>&nbsp;&nbsp;&nbsp; public static void makeAllNewsInfoIndex(List newsList)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; List terms = new ArrayList();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; List docs = new ArrayList(); 
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; newsList.size(); i++)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NewsItem aitem = (NewsItem) newsList.get(i);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (null != aitem)<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; terms.add(new Term("nid", String.valueOf(aitem.getNid())));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; docs.add(makeNewsSearchDocument(aitem));<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; deleteIndex(terms,indexDir);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; makeIndex(docs,indexDir);<BR>&nbsp;&nbsp;&nbsp; }&nbsp;</P></TD></TR></TBODY></TABLE><BR><BR>&nbsp;<BR>&nbsp;<BR>&nbsp;下一节讲解如何对要建立索引的内容进行解析,例如解析Html等内容.<BR></P><img src ="http://www.blogjava.net/scud/aggbug/9979.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/scud/" target="_blank">Scud(飞云小侠)</a> 2005-08-12 17:31 <a href="http://www.blogjava.net/scud/archive/2005/08/12/9979.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>分析/解析Html页面:HTML Parser的试用 </title><link>http://www.blogjava.net/scud/archive/2005/08/11/9846.html</link><dc:creator>Scud(飞云小侠)</dc:creator><author>Scud(飞云小侠)</author><pubDate>Thu, 11 Aug 2005 14:31:00 GMT</pubDate><guid>http://www.blogjava.net/scud/archive/2005/08/11/9846.html</guid><wfw:comment>http://www.blogjava.net/scud/comments/9846.html</wfw:comment><comments>http://www.blogjava.net/scud/archive/2005/08/11/9846.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/scud/comments/commentRss/9846.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/scud/services/trackbacks/9846.html</trackback:ping><description><![CDATA[<P>作者:scud(飞云小侠)&nbsp; <A href="http://www.jscud.com/">http://www.jscud.com</A>&nbsp; 转载请注明作者来源.否则请勿转载,谢谢.</P>
<P>最近在研究lucene的全文检索,在很多地方需要解析或者说分析Html内容或者Html页面,Lucene本身的演示程序中也提供了一个Html Parser,但是不是纯Java的解决方案.于是到处搜索,在网上找到了一个"HTMLParser".</P>
<P>网址是: <A href="http://htmlparser.sourceforge.net/">http://htmlparser.sourceforge.net</A>&nbsp;,当前版本为1.5. </P>
<P>下载下来,试用一番,感觉不错,完全能满足lucene解析Html的需求.</P>
<P>过几天贴出lucene进行全文检索的代码.(检索本站的文章等).</P>
<P>试用代码如下,供大家参考:</P>
<P>
<TABLE class=code cellSpacing=1 cellPadding=1 width="80%" align=center border=0>
<TBODY>
<TR>
<TD>
<P>package com.jscud.test;</P>
<P>import java.io.BufferedReader;<BR>import java.io.File;<BR>import java.io.FileInputStream;<BR>import java.io.InputStreamReader;</P>
<P>import org.htmlparser.Node;<BR>import org.htmlparser.NodeFilter;<BR>import org.htmlparser.Parser;<BR>import org.htmlparser.filters.NodeClassFilter;<BR>import org.htmlparser.filters.OrFilter;<BR>import org.htmlparser.nodes.TextNode;<BR>import org.htmlparser.tags.LinkTag;<BR>import org.htmlparser.util.NodeList;<BR>import org.htmlparser.util.ParserException;<BR>import org.htmlparser.visitors.HtmlPage;<BR>import org.htmlparser.visitors.TextExtractingVisitor;</P>
<P>import com.jscud.util.LogMan; //一个日志记录类</P>
<P>/**<BR>&nbsp;* 演示了Html Parse的应用.<BR>&nbsp;* <BR>&nbsp;* @author scud <A href="http://www.jscud.com/">http://www.jscud.com</A><BR>&nbsp;*/</P>
<P>public class ParseHtmlTest<BR>{</P>
<P>&nbsp;&nbsp;&nbsp; public static void main(String[] args) throws Exception<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String aFile = "e:/jscud/temp/test.htm";</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String content = readTextFile(aFile, "GBK");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; test1(content);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("====================================");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; test2(content);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("====================================");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; test3(content);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("====================================");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; test4(content);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("====================================");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; test5(aFile);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("====================================");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //访问外部资源,相对慢<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; test5("<A href="http://www.jscud.com/">http://www.jscud.com</A>"); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("====================================");</P>
<P>&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; /**<BR>&nbsp;&nbsp;&nbsp;&nbsp; * 读取文件的方式来分析内容.<BR>&nbsp;&nbsp;&nbsp;&nbsp; * filePath也可以是一个Url.<BR>&nbsp;&nbsp;&nbsp;&nbsp; * <BR>&nbsp;&nbsp;&nbsp;&nbsp; * @param resource 文件/Url<BR>&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp; public static void test5(String resource) throws Exception<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Parser myParser = new Parser(resource);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //设置编码<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myParser.setEncoding("GBK");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HtmlPage visitor = new HtmlPage(myParser);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myParser.visitAllNodesWith(visitor);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String textInPage = visitor.getTitle();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(textInPage);<BR>&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; /**<BR>&nbsp;&nbsp;&nbsp;&nbsp; * 按页面方式处理.对一个标准的Html页面,推荐使用此种方式.<BR>&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp; public static void test4(String content) throws Exception<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Parser myParser;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myParser = Parser.createParser(content, "GBK");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HtmlPage visitor = new HtmlPage(myParser);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myParser.visitAllNodesWith(visitor);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String textInPage = visitor.getTitle();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(textInPage);<BR>&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; /**<BR>&nbsp;&nbsp;&nbsp;&nbsp; * 利用Visitor模式解析html页面.<BR>&nbsp;&nbsp;&nbsp;&nbsp; *<BR>&nbsp;&nbsp;&nbsp;&nbsp; * 小优点:翻译了&lt;&gt;等符号 <BR>&nbsp;&nbsp;&nbsp;&nbsp; * 缺点:好多空格,无法提取link<BR>&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp; public static void test3(String content) throws Exception<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Parser myParser;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myParser = Parser.createParser(content, "GBK");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TextExtractingVisitor visitor = new TextExtractingVisitor();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myParser.visitAllNodesWith(visitor);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String textInPage = visitor.getExtractedText();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(textInPage);<BR>&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; /**<BR>&nbsp;&nbsp;&nbsp;&nbsp; * 得到普通文本和链接的内容.<BR>&nbsp;&nbsp;&nbsp;&nbsp; * <BR>&nbsp;&nbsp;&nbsp;&nbsp; * 使用了过滤条件.<BR>&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp; public static void test2(String content) throws ParserException<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Parser myParser;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NodeList nodeList = null;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myParser = Parser.createParser(content, "GBK");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NodeFilter textFilter = new NodeClassFilter(TextNode.class);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NodeFilter linkFilter = new NodeClassFilter(LinkTag.class);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //暂时不处理 meta<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //NodeFilter metaFilter = new NodeClassFilter(MetaTag.class);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OrFilter lastFilter = new OrFilter();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lastFilter.setPredicates(new NodeFilter[] { textFilter, linkFilter });</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nodeList = myParser.parse(lastFilter);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Node[] nodes = nodeList.toNodeArray();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; nodes.length; i++)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Node anode = (Node) nodes[i];</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String line = "";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (anode instanceof TextNode)<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; TextNode textnode = (TextNode) anode;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //line = textnode.toPlainTextString().trim();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line = textnode.getText();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if (anode instanceof LinkTag)<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; LinkTag linknode = (LinkTag) anode;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line = linknode.getLink();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A>//@todo</A> 过滤jsp标签:可以自己实现这个函数<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //line = StringFunc.replace(line, "&lt;%.*%&gt;", "");<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; if (isTrimEmpty(line))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(line);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; /**<BR>&nbsp;&nbsp;&nbsp;&nbsp; * 解析普通文本节点.<BR>&nbsp;&nbsp;&nbsp;&nbsp; * <BR>&nbsp;&nbsp;&nbsp;&nbsp; * @param content<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @throws ParserException<BR>&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp; public static void test1(String content) throws ParserException<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Parser myParser;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Node[] nodes = null;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myParser = Parser.createParser(content, null);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nodes = myParser.extractAllNodesThatAre(TextNode.class); //exception could be thrown here</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; nodes.length; i++)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TextNode textnode = (TextNode) nodes[i];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String line = textnode.toPlainTextString().trim();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (line.equals(""))<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; System.out.println(line);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; /**<BR>&nbsp;&nbsp;&nbsp;&nbsp; * 读取一个文件到字符串里.<BR>&nbsp;&nbsp;&nbsp;&nbsp; * <BR>&nbsp;&nbsp;&nbsp;&nbsp; * @param sFileName&nbsp; 文件名<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @param sEncode&nbsp;&nbsp; String<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @return 文件内容<BR>&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp; public static String readTextFile(String sFileName, String sEncode)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StringBuffer sbStr = new StringBuffer();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File ff = new File(sFileName);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InputStreamReader read = new InputStreamReader(new FileInputStream(ff),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sEncode);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BufferedReader ins = new BufferedReader(read);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String dataLine = "";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (null != (dataLine = ins.readLine()))<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; sbStr.append(dataLine);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sbStr.append("\r\n");<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; ins.close();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch (Exception e)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LogMan.error("read Text File Error", e);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return sbStr.toString();<BR>&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; /**<BR>&nbsp;&nbsp;&nbsp;&nbsp; * 去掉左右空格后字符串是否为空<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @param astr String<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @return boolean<BR>&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp; public static boolean isTrimEmpty(String astr)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((null == astr) || (astr.length() == 0))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (isBlank(astr.trim()))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;<BR>&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; /**<BR>&nbsp;&nbsp;&nbsp;&nbsp; * 字符串是否为空:null或者长度为0.<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @param astr 源字符串.<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @return boolean<BR>&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp; public static boolean isBlank(String astr)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((null == astr) || (astr.length() == 0))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }</P>
<P>}</P>
<P>&nbsp;</P></TD></TR></TBODY></TABLE><BR></P><img src ="http://www.blogjava.net/scud/aggbug/9846.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/scud/" target="_blank">Scud(飞云小侠)</a> 2005-08-11 22:31 <a href="http://www.blogjava.net/scud/archive/2005/08/11/9846.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>