2008年12月31日星期三

wtp-all-in-one-sdk-R-1.5.4-win32(转)

摘自:http://yjcoffee.javaeye.com/blog/114050

关键字: Eclipse Europa
在6月份Eclipse发布Europa后,我就把喜爱的wtp-all-in-one-1.5.4升级到了wtp-all-in-one-2.0,尽管没有发现多少wtp-2.0的新鲜特性,但这两个月下来,用的感觉还是不错地(据说是速度快了,我也觉得,但可能是心里因素吧:)

但是昨天为了装一个Maven2的插件m2eclipse就出现了一个非常诡异的问题,由于m2eclipse-0.0.10不能发现 M2_HOME\conf\settings.xml中配置的localRepository,只好重新装上老的版本m2eclipse-0.0.5。启 动Eclipse即发现好多wtp的功能都不见了,包括xml、jsp编辑器 等,server配置也出现问题,找不到原来的Apache、BEA等runtime,只在Basic节点下面出现一个红色标识的HTTP Server,并提示我Download additional server adapters --见附图

开始以为是插件冲突的缘故,于是卸了所有插件(本人使用link方式安装),重启Eclipse--发现不行;于是乎,干脆删除整个Eclipse及 workspace,重新解压缩wtp-all-in-one-2.0,启动后还是发现那些功能不可用--真诡异了。这是打开plugins details时发现一个现象,plugin列表第一列叫signed,而那些不可用的功能插件的状态均为unsigned。找了半天能sign这些插件 的地方也找不到,于是只好在google上面求助。

中文的英文的找了好久,只发现一个中文博客的文章描述的和我一样(http://koctr.blog.sohu.com/53844001.html),文章最后的也只有说装回wtp-all-in-one-1.5.4,这也最后成了我放弃Europa的无奈之举。今天一直耿耿于怀,于是发到了JavaEye向广大Eclipse用户及高手寻求解决办法
  • A44dc3a2-91f5-4012-8fe9-0f2d7e93e10b-thumb
  • 大小: 97.9 KB
评论
fujohnwang 2007-08-22   回复
我的Eclipse3.3怎么是不是的源码上老出现变异那个红叉?!可是实际上代码没有问题,who know how to fix this?
Sam1860 2007-08-22   回复
是自己的问题别怪到工具上,我的wtp2+m2eclipse用得好好的
yjcoffee 2007-08-20   回复
感谢楼上的几位,问题已经找到了:我JDK的版本是1.5的,但由于环境变量PATH中%SystemRoot%\system32放在了%JAVA_HOME%\bin前面(最近整理PATH路径时忽略了),因此最终启动Eclipse 3.3使用的是IBM自带的J2RE 1.4.2,所以导致Eclipse部分插件功能无法使用,错怪了可爱的Europa 

--希望大家不要像我这样粗心大意,呵呵 

BTW: Maven正在熟悉过程中,希望能有个好用的plugin才尝试m2eclipse了,也错怪它了。。。
maqujun 2007-08-20   回复
拜托,Europa是我用到现在最好的Eclipse版本。wtp-2.0也非常好用。至于maven2,就像二楼说的直接写pom.xml,再用bat运行,就当他ant用,不就行了。
Spirit Wang 2007-08-20   回复
请使用JDK1.5
gof95 2007-08-20   回复
我见过同样的现象,是因为jdk版本过低造成的
dengyin2000 2007-08-20   回复
yjcoffee 写道
各位就不要责怪我为嘛安装m2eclipse插件吧,问题是我现在重装Eclipse 3.3不带任何插件好多诸如xml编辑器等功能都不可用,转载的那篇博客也是从MyEclipse转向Eclipse 3.3的,没有提到安装插件的问题,最后结果也是和我一样,难道大家就没有出现这种问题吗?那也太奇怪了,我是不是该向Eclipse.org提交一个Bug验证一下。。。


为什么我这里好好的。  公司的ubuntu 和  家里的xp 都ok。。
yjcoffee 2007-08-20   回复
各位就不要责怪我为嘛安装m2eclipse插件吧,问题是我现在重装Eclipse 3.3不带任何插件好多诸如xml编辑器等功能都不可用,转载的那篇博客也是从MyEclipse转向Eclipse 3.3的,没有提到安装插件的问题,最后结果也是和我一样,难道大家就没有出现这种问题吗?那也太奇怪了,我是不是该向Eclipse.org提交一个Bug验证一下。。。
dengyin2000 2007-08-19   回复
用maven为什么要用eclipse插件。  敲命令还更爽

2008年12月30日星期二

开源的IM和VoIP组合

wildfire + jabbin + jwchat 太棒了..

wildfire是一个功能强大的jabber服务器,基于java,安装相当简单,只要从官文网站下载rpm包,安装一下就OK了.
其支持web方式的管理,支持服务器到服务器的连接,并且有许多好用的免费插件.

jabbin是支持VoIP的jabber客户端,和PSI是同宗同源,支持语音.

iwchat是基于web的jabber客户端

2008年12月29日星期一

认识XML中的XPath介绍(转)

摘自:http://www.webjx.com/htmldata/2005-05-07/1115402769.html


  之所以要引入XPath的概念,目的就是为了在匹配XML文档结构树时能够准确地找到某一个节点元素。可以把XPath比作文件管理路径:通过 文件管理路径,可以按照一定的规则查找到所需要的文件;同样,依据XPath所制定的规则,也可以很方便地找到XML结构文档树中的任何一个节点.

  不过,由于XPath可应用于不止一个的标准,因此W3C将其独立出来作为XSLT的配套标准颁布,它是XSLT以及我们后面要讲到的XPointer的重要组成部分。

  在介绍XPath的匹配规则之前,我们先来看一些有关XPath的基本概念。

  首先要说的是XPath数据类型。XPath可分为四种数据类型:

  1. 节点集(node-set)
    节点集是通过路径匹配返回的符合条件的一组节点的集合。其它类型的数据不能转换为节点集。
  2. 布尔值(boolean)
    由函数或布尔表达式返回的条件匹配值,与一般语言中的布尔值相同,有true和false两个值。布尔值可以和数值类型、字符串类型相互转换。
  3. 字符串(string)
    字符串即包含一系列字符的集合,XPath中提供了一系列的字符串函数。字符串可与数值类型、布尔值类型的数据相互转换。
  4. 数值(number)
    在XPath中数值为浮点数,可以是双精度64位浮点数。另外包括一 些数值的特殊描述,如非数值NaN(Not-a-Number)、正无穷大infinity、负无穷大-infinity、正负0等等。number的整 数值可以通过函数取得,另外,数值也可以和布尔类型、字符串类型相互转换。

  其中后三种数据类型与其它编程语言中相应的数据类型差不多,只是第一种数据类型是XML文档树的特有产物。

  另外,由于XPath包含的是对文档结构树的一系列操作,因此搞清楚XPath节点类型也是很必要的。回忆一下第二章中讲到的XML文档的逻辑 结构,一个XML文件可以包含元素、CDATA、注释、处理指令等逻辑要素,其中元素还可以包含属性,并可以利用属性来定义命名空间。相应地,在 XPath中,将节点划分为七种节点类型:

  1. 根节点(Root Node)
    根节点是一棵树的最上层,根节点是唯一的。树上其它所有元素节点都是它的子节点或后代节点。对根节点的处理机制与其它节点相同。在XSLT中对树的匹配总是先从根节点开始。
  2. 元素节点(Element Nodes)
    元素节点对应于文档中的每一个元素,一个元素节点的子节点可以是元素节点、注释节点、处理指令节点和文本节点。可以为元素节点定义一个唯一的标识id。
    元素节点都可以有扩展名,它是由两部分组成的:一部分是命名空间URI,另一部分是本地的命名。
  3. 文本节点(Text Nodes)
    文本节点包含了一组字符数据,即CDATA中包含的字符。任何一个文本节点都不会有紧邻的兄弟文本节点,而且文本节点没有扩展名。
  4. 属性节点(Attribute Nodes)
    每一个元素节点有一个相关联的属性节点集合, 元素是每个属性节点的父节点,但属性节点却不是其父元素的子节点。这就是说,通过查找元素的子节点可以匹配出元素的属性节点,但反过来不成立,只是单向 的。再有,元素的属性节点没有共享性,也就是说不同的元素节点不共有同一个属性节点。
    对缺省属性的处理等同于定义了的属性。如果一个属性是在DTD声明的,但声明为#IMPLIED,而该属性没有在元素中定义,则该元素的属性节点集中不包含该属性。
    此外,与属性相对应的属性节点都没有命名空间的声明。命名空间属性对应着另一种类型的节点。
  5. 命名空间节点(Namespace Nodes)
    每一个元素节点都有一个相关的命名空间节点集。在XML文档中,命名空间是通过保留属性声明的,因此,在XPath中,该类节点与属性节点极为相似,它们与父元素之间的关系是单向的,并且不具有共享性。
  6. 处理指令节点(Processing Instruction Nodes)
    处理指令节点对应于XML文档中的每一条处理指令。它也有扩展名,扩展名的本地命名指向处理对象,而命名空间部分为空。
  7. 注释节点(Comment Nodes)
    注释节点对应于文档中的注释。

下面,我们来构造一棵XML文档树,作为后面举例的依托:

<A id="a1">
  <B id="b1">
    <C id="c1">
      <B name="b"/>
      <D id="d1"/>
      <E id="e1"/>
      <E id="e2"/>
    </C>
  </B>
  <B id="b2"/>
  <C id="c2">
    <B/>
    <D id="d2"/>
    <F/>
  </C>
  <E/>
</A>

现在,我们就来介绍一些XPath中节点匹配的基本方法。

  1. 路径匹配
    路径匹配与文件路径的表示相仿,比较好理解。有以下几个符号:
    符  号 含  义 举  例 匹配结果
    / 指示节点路径 /A/C/D 节点"A"的子节点"C"的子节点"D",即id值为d2的D节点
    / 根节点
    // 所有路径以"//"后指定的子路径结尾的元素 //E 所有E元素,结果是所有三个E元素
    //C/E 所有父节点为C的E元素,结果是id值为e1和e2的两个E元素
    * 路径的通配符 /A/B/C/* A元素→B元素→C元素下的所有子元素,即name值为b的B元素、id值为d1的D元素和id值为e1和e2的两个E元素
    /*/*/D 上面有两级节点的D元素,匹配结果是id值为d2的D元素
    //* 所有的元素
    | 逻辑或 //B | //C 所有B元素和C元素


  2. 位置匹配
    对于每一个元素,它的各个子元素是有序的。如:
    举  例 含  义 匹配结果
    /A/B/C[1] A元素→B元素→C元素的第一个子元素 name值为b的B元素
    /A/B/C[last()] A元素→B元素→C元素的最后一个子元素 id值为e2的E元素
    /A/B/C[position()>1] A元素→B元素→C元素之下的位置号大于1的元素 id值为d1的D元素和两个具有id值的E元素


  3. 属性及属性
    在XPath中可以利用属性及属性值来匹配元素,要注意的是,元素的属性名前要有"@"前缀。例如:
    举  例 含  义 匹配结果
    //B[@id] 所有具有属性id的B元素 id值为b1和b2的两个B元素
    //B[@*] 所有具有属性的B元素 两个具有id属性的B元素和一个具有name属性B元素
    //B[not(@*)] 所有不具有属性的B元素 A元素→C元素下的B元素
    //B[@id="b1"] id值为b1的B元素 A元素下的B元素


  4. 亲属关系匹配
    XML文档可归结为树型结构,因此任何一个节点都不是孤立的。通常我们把节点之间的归属关系归结为一种亲属关系,如父亲、孩子、祖先、后代、兄弟等等。在对元素进行匹配时,同样可以用到这些概念。例如:
    举  例 含  义 匹配结果
    //E/parent::* 所有E节点的父节点元素 id值为a1的A元素和id值为c1的C元素
    //F/ancestor::* 所有F元素的祖先节点元素 id值为a1的A元素和id值为c2的C元素
    /A/child::* A的子元素 id值为b1、b2的B元素,id值为c2的C元素,以及没有任何属性的E元素
    /A/descendant::* A的所有后代元素 除A元素以外的所有其它元素
    //F/self::* 所有F的自身元素 F元素本身
    //F/ancestor-or-self::* 所有F元素及它的祖先节点元素 F元素、F元素的父节点C元素和A元素
    /A/C/descendant-or-self::* 所有A元素→C元素及它们的后代元素 id值为c2的C元素、该元素的子元素B、D、F元素
    /A/C/following-sibling::* A元素→C元素的紧邻的后序所有兄弟节点元素 没有任何属性的E元素
    /A/C/preceding-sibling::* A元素→C元素的紧邻的前面所有兄弟节点元素 id值为b1和b2的两个B元素
    /A/B/C/following::* A元素→B元素→C元素的后序的所有元素 id为b2的B元素、无属性的C元素、无属性的B元素、id为d2的D元素、无属性的F元素、无属性的E元素。
    /A/C/preceding::* A元素→C元素的前面的所有元素 id为b2的B元素、id为e2的E元素、id为e1的E元素、id为d1的D元素、name为b的B元素、id为c1的C元素、id为b1的B元素


  5. 条件匹配
    条件匹配就是利用一些函数的运算结果的布尔值来匹配符合条件的节点。常用于条件匹配的函数有四大类:节点函数、字符串函数、数值函数、布尔函数。例如前面提到的last()、position()等等,这里我们就不再赘述。

以上这些匹配方法中,用得最多的还要数路径匹配。

JDOM/XPATH编程指南(转)

摘自:http://www-128.ibm.com/developerworks/cn/xml/x-jdom/


级别: 初级

薛谷雨 (rainight@126.com), 高级JAVA工程师, NORDSAN信息科技开发有限公司

2004 年 5 月 01 日

本文分别介绍了 JDOM 和 XPATH,以及结合两者进行 XML 编程带来的好处。

前言

XML 是一种优秀的数据打包和数据交换的形式,在当今XML大行于天下,如果没有听说过它的大名,那可真是孤陋寡闻了。用XML描述数据的优势显而易见,它具有 结构简单,便于人和机器阅读的双重功效,并弥补了关系型数据对客观世界中真实数据描述能力的不足。W3C组织根据技术领域的需要,制定出了XML的格式规 范,并相应的建立了描述模型,简称DOM。各种流行的程序设计语言都纷纷根据这一模型推出了自己的XML解析器,在JAVA世界里,APACHE组织开发 的XERCES应该是流行最广功能最为强大的XML解析器之一。但是由于W3C在设计DOM模型时,并不是针对某一种语言而设计,因此为了通用性,加入了 许多繁琐而不必要的细节 ,使JAVA程序员在开发XML的应用程序过程中感到不甚方便,因此JDOM作为一种新型的XML解析器横空出世,它不遵循DOM模型,建立了自己独立的 一套JDOM模型(注意JDOM决不是DOM扩展,虽然名字差不多,但两者是平行的关系),并提供功能强大使用方便的类库,使JAVA程序员可以更为高效 的开发自己的XML应用程序,并极大的减少了代码量,因此它很快得到了业内的认可,如JBUILDER这样的航空母舰级的重磅产品都以JDOM为XML解 析引擎,足见其名不虚传。

有了XML数据的描述标准,人们自然就会想到应该有一种查询语言可以在XML中查找任意节点的数 据,就像SQL语句可以在关系性数据库中执行查询操作一样,于是XQUERY和XPATH顺应潮流,应运而生。由于XQUERY较为复杂,使用不甚方 便,XPATH渐渐成为主流,我们只需对XPATH进行学习,便可以应付所有的查询要求。在JDOM发布的最新的V1.0bata10版中,已经加入了对 XPATH的支持,这无疑是令开发者十分激动的。

学会JDOM和XPATH,你便不再是XML的入门者,在未来的开发生涯中,就像特种兵的多用匕首,为你披荆斩棘,助你勇往直前。闲言少叙,学习还要脚踏实地,从头开始。





回页首


XPATH速成篇

XPATH 遵循文档对象模型(DOM)的路径格式,由于每个XML文档都可以看成是一棵拥有许多结点的树,每个结点可以是以下七个类型之一:根(root)、元素 (element)、属性(attribute)、正文(text)、命名空间(namespace)、处理指令(processing instruction)和注释(comment)。XPATH的基本语法由表达式构成。在计算表达式的值之后产生一个对象,这种对象有以下四种基本类 型:节点集合、布尔型、数字型和字符串型 。XPATH基本上和在文件系统中寻找文件类似,如果路径是以"/"开头的,就表明该路径表示的是一个绝对路径,这和在UNIX系统中关于文件路径的定义 是一致的。以"//"开头则表示在文档中的任意位置查找。

不谈泛泛的理论,学习XPATH还要从实例学起最为快捷,并有助于你举一反三。

下 面的样例XML文档,描述了某台电脑中硬盘的基本信息(根节点<HD>代表硬盘,<disk>标签代表硬盘分区,从它的name 属性可以看出有两个盘符名称为"C"和"D"的分区;每个分区下都包 含<capacity>,<directories><files>三个节点,分别代表了分区的空间大小、目录数 量、所含文件个数):

<?xml version="1.0" encoding="UTF-8"?>
<HD>
<disk name="C">
<capacity>8G</capacity>
<directories>200</directories>
<files>1580</files>
</disk>
<disk name="D">
<capacity>10G</capacity>
<directories>500</directories>
<files>3000</files>
</disk>
</HD>

你在XML文档中使用位置路径表达式来查找信息,这些表达式有很多种组成方式。

结点元素的查找是你将要碰到的最频繁的查找方式。在上面这个XML文档例子中,根HD包含disk结点。你可以使用路径来查找这些结点,用正斜杠(/)来分隔子结点,返回所有与模式相匹配的元素。下面的XPATH 语句返回所有的disk元素:

/HD/disk

"*"代表"全部"的意思。/HD/* 代表HD下的全部节点。

下面的XPATH将返回任意节点下的名称为disk的全部节点:

//disk

下面的XPATH将返回名称为disk,name属性为'C'的全部节点:

/HD/disk[@name='C']

节点的附加元素,比如属性,函数等都要用方括号扩起来,属性前面要加上@号

下面的XPATH将返回文件个数为1580的files节点:

/HD/disk/files[text()='1580']

大家注意到上面包含一个text(),这就是XPATH的一个函数,它的功能是取出当前节点的文本。

下面的XPATH将返回文件个数为1580的分区:

/HD/disk/files[text()='1580']/parent::*

最后的parent::*表示这个元素的所有的父节点的集合。

XPATH中一些有用的函数:

string concat (string, string, string*) 联接两个字符串
boolean starts-with (string, string) 判断某字符串是否以另一字符串开头
boolean contains (string, string) 判断某字符串是否包含另一字符串
string substring (string, number, number) 取子字符串
number string-length (string) 测字符串长度
number sum (node-set) 求和
number floor (number) 求小于此数的最大整数值
number ceiling (number) 求大于此数最小整数值

XPATH 具有丰富的表达功能,上面这些已经基本够用,在你做项目中就会发现根据实际情况有许多查询需求,你应该参考本文最后提供的W3C发布的关于XAPH的官方 资料进行查阅,我在这里只起一个抛砖引玉的作用,在下面的章节中,我们的应用范例将不会超出上面提到的这些内容,如果你对XPATH感兴趣,应该在读完本 文后,查找相关资料和书籍进行深入学习。





回页首


JDOM修炼篇

用过XERCES的程序员都会感到,有时候用一句话就可以说清楚的事,当用XERCES的API来实现时,要三四行程序。





回页首


获得并安装JDOM

http://www.jdom.org/可以下载JDOM的最新版本,将压缩包中的jdom.jar及lib目录下的全部jar包加入到classpath就可以了。





回页首


用JDOM解析XML

JDOM 模型的全部类都在org.jdom.*这个包里,org.jdom.input.*这个包里包含了JDOM的解析器,其中的DOMBuilder的功能是 将DOM模型的Document解析成JDOM模型的Document;SAXBuilder的功能是从文件或流中解析出符合JDOM模型的XML树。由 于我们的上面提到的XML样例存储在一个名称为sample.xml的文件中,很显然我们应该采用后者作为解析工具。下面程序演示了jdom的基本功能, 即解析一个xml文档,并挑选一些内容输出到屏幕上。

import java.util.*;
import org.jdom.*;
import org.jdom.input.SAXBuilder;
public class Sample1 {
public static void main(String[] args) throws Exception{
SAXBuilder sb=new SAXBuilder();
Document doc=sb.build("sample.xml");
Element root=doc.getRootElement();
List list=root.getChildren("disk");
for(int i=0;i<list.size();i++){
Element element=(Element)list.get(i);
String name=element.getAttributeValue("name");
String capacity=element.getChildText("capacity");
String directories=element.getChildText("directories");
String files=element.getChildText("files");
System.out.println("磁盘信息:");
System.out.println("分区盘符:"+name);
System.out.println("分区容量:"+capacity);
System.out.println("目录数:"+directories);
System.out.println("文件数:"+files);
System.out.println("-----------------------------------");
}
}
}

程序的输出结果:

磁盘信息:
分区盘符:C
分区容量:8G
目录数:200
文件数:1580
-----------------------------------
磁盘信息:
分区盘符:D
分区容量:10G
目录数:500
文件数:3000
-----------------------------------

这段程序采用了传统的解析方式,一级一级的从根节点到子节点逐个采集我们所需要的数据,中规中矩。试想如果这个树足够深,我们想取第5 0层第三个节点的数据(夸张了点,呵呵),那将是一场噩梦!下面的内容将轻松化解你的这一痛苦。





回页首


JDOM+XPATH进阶篇

说了那么多JDOM和XPATH的好处,终于到了英雄有用武之地的时候了。

JDOM 的关于XPATH的api在org.jdom.xpath这个包里。看看这个包下,只有一个类,JDOM就是如此简洁,什么事都不故弄玄虚的搞得那么复 杂。这个类中的核心的api主要是两个selectNodes()和selectSingleNode()。前者根据一个xpath语句返回一组节点;后 者根据一个xpath语句返回符合条件的第一个节点。

下面的程序我们用JDOM+XPATH实现了上一个程序同样的功能,你可以从中学到不少运用XPATH 的知识:

import java.util.*;
import org.jdom.*;
import org.jdom.input.SAXBuilder;
import org.jdom.xpath.XPath;
public class Sample2 {
public static void main(String[] args) throws Exception {
SAXBuilder sb = new SAXBuilder();
Document doc = sb.build("sample.xml");
Element root = doc.getRootElement();
List list = XPath.selectNodes(root, "/HD/disk");
for (int i = 0; i > list.size(); i++) {
Element disk_element = (Element) list.get(i);
String name = disk_element.getAttributeValue("name");
String capacity = ( (Text) XPath.selectSingleNode(disk_element,
"//disk[@name='" + name + "']/capacity/text()")).getTextNormalize();
String directories = ( (Text) XPath.selectSingleNode(disk_element,
"//disk[@name='" + name + "']/directories/text()")).getTextNormalize();
String files = ( (Text) XPath.selectSingleNode(disk_element,
"//disk[@name='" + name + "']/files/text()")).getTextNormalize();
System.out.println("磁盘信息:");
System.out.println("分区盘符:" + name);
System.out.println("分区容量:" + capacity);
System.out.println("目录数:" + directories);
System.out.println("文件数:" + files);
System.out.println("-----------------------------------");
}
}
}

输出结果:

磁盘信息:
分区盘符:C
分区容量:8G
目录数:200
文件数:1580
-----------------------------------
磁盘信息:
分区盘符:D
分区容量:10G
目录数:500
文件数:3000
-----------------------------------





回页首


结语

技 术在日新月异的发展。永远没有学过后,便可以一劳永逸的技术。XML的发展一日千里。W3C作为INTERNET方面的权威组织指导着互联网技术的发展方 向。新技术的出现大都围绕着W3C制订的标准,但往往有些"旁门左道"的另类功法却能产生惊人的杀伤力。JDOM就是这众多旁门中的一朵奇葩。就像 J2EE大行其道的今天,有许多开源组织仍旧在默默的打造着自己的独家兵器,谁又能说在不久的将来,他们不会成为划时代的创造呢? 君不见Hibernate的兴起正在有力的震撼着J2EE中EJB架构的基石。只要是成型的框架,必然有薄弱的软肋。新的技术只要能攻入对方这一弱点,便 可在业界站一席之地。本文只起抛砖引玉的作用,相信读者在吃过这道快餐之后,一定会发现窗外有更美丽的风景等待我们去游历。



参考资料



关于作者


薛谷雨是NORDSAN(北京)信息科技开发有限公司高级JAVA研发工程师,正致力于企业级异构数据交换的服务器产品的研发,在J2EE和WEB SERVICE方面有较为丰富的开发经验,你可以通过 rainight@126.com与他取得联系。

HOW TO:使用 Visual C# .NET 通过 XPath 表达式查询 XML(转)

摘自:http://support.microsoft.com/kb/308333/zh-cn

本文演示如何使用 XPathNavigator 类通过 XML 路径语言 (XPath) 表达式查询 XPathDocument 对象。XPath 用于以编程方式计算表达式并选择文档中的特定节点。

要求

下面的列表列出了推荐使用的硬件、软件、网络基础结构以及所需的服务包:
  • Visual C# .NET
本文假定您熟悉下列主题:
  • XML 术语
  • 创建和读取 XML 文件
  • XPath 语法

如何用 XPath 表达式查询 XML

  1. 在 Visual Studio .NET 中新建一个 Visual C# .NET 控制台应用程序。

    备注: 本示例使用名为 Books.xml 的文件。您可以创建自己的 Books.xml 文件,也可以使用 .NET 软件开发工具包 (SDK) 快速入门中包括的示例。如果您没有安装"快速入门"而且也不想安装它们,请参阅 Books.xml 下载位置的"参考"部分。如果已经安装了"快速入门",则该文件位于以下文件夹中:
    Program Files\Microsoft.NET\FrameworkSDK\Samples\Quickstart\Howto\Samples\Xml\Transformxml\VB
    必须将该文件复制到 \Bin\Debug 文件夹,该文件夹位于您在其中创建该项目的文件夹中。
  2. 确保该项目引用 System.Xml 名称空间。
  3. Xml XPath 名称空间上使用 using 语句,这样以后就不需要在代码中限定这些名称空间中的声明了。using 语句必须在所有其他声明之前使用,如下所示:
     using System.Xml;
    using System.Xml.XPath;
  4. 声明合适的变量。声明 XPathDocument 对象以保存 XML 文档,声明 XpathNavigator 对象以计算 XPath 表达式,声明 XPathNodeIterator 对象以迭代通过选定节点。声明 String 对象以保存 XPath 表达式。在 Class1 的 Main 函数中添加声明代码。
    XPathNavigator nav; 
    XPathDocument docNav;
    XPathNodeIterator NodeIter;
    String strExpression;
  5. 用示例文件 Books.xml 加载 XPathDocumentXPathDocument 类使用可扩展样式表语言转换 (XSLT) 为 XML 文档处理提供快速和面向性能的缓存。它类似于 XML 文档对象模型 (DOM),但经过了高度优化,以用于 XSLT 处理和 XPath 数据模型。
    // Open the XML.
    docNav = new XPathDocument(@"c:\books.xml");
  6. 从文档创建 XPathNavigatorXPathNavigator 对象用于进行只读 XPath 查询。XPath 查询可返回结果值或许多节点。
    // Create a navigator to query with XPath.
    nav = docNav.CreateNavigator();
  7. 创建 XPath 表达式以查找图书的平均价格。这个 XPath 表达式返回单个值。有关 XPath 语法的完整详细信息,请参见"参考"部分中的"XPath 语法"。
    // Find the average cost of a book.
    // This expression uses standard XPath syntax.
    strExpression = "sum(/bookstore/book/price) div count(/bookstore/book/price)";
  8. 使用 XPathNavigator 对象的 Evaluate 方法计算 XPath 表达式。Evaluate 方法返回该表达式的结果。
    // Use the Evaluate method to return the evaluated expression.
    Console.WriteLine("The average cost of the books are {0}", nav.Evaluate(strExpression));
  9. 创建 XPath 表达式以查找价格超过 10 美元的所有图书。这个 XPath 表达式只从 XML 源中返回 Title 节点。
    // Find the title of the books that are greater then $10.00.
    strExpression = "/bookstore/book/title[../price>10.00]";
  10. 为使用 XPathNavigator Select 方法选择的节点创建 XPathNodeIteratorXPathNodeIterator 表示 XPath 节点集,因此它支持针对该节点集执行的操作。
    // Select the node and place the results in an iterator.
    NodeIter = nav.Select(strExpression);
  11. 使用从 XPathNavigator Select 方法返回的 XPathNodeIterator 遍历选定的节点。在这种情况下,可使用 XPathNodeIterator MoveNext 方法迭代通过选定的所有节点。
    Console.WriteLine("List of expensive books:");
    //Iterate through the results showing the element value.
    while (NodeIter.MoveNext())
    {
    Console.WriteLine("Book Title:{0}", NodeIter.Current.Value);
    };
  12. 使用 ReadLine 方法在控制台显示的末尾添加 pause,以便更容易地显示上述结果。
    //Pause
    Console.ReadLine();
  13. 生成并运行您的项目。请注意,这些结果显示在控制台窗口中。

疑难解答

在测试代码时,您可能会收到以下异常错误信息:
An unhandled exception of type 'System.Xml.XmlException' occurred in System.xml.dll

Additional information:System error.
该异常错误发生在以下代码行上:
docNav = new XPathDocument("c:\\books.xml");
该异常错误是由无效的处理指令导致的。例如,处理指令可能包含多余的空格。下面是无效处理指令的示例:
<?xml version='1.0'?>
若要解决该异常,请执行以下操作之一:
  • 纠正无效的处理指令。下面是有效处理指令的示例:
    <?xml version='1.0'?>
    - 或 -
  • 下面是有效处理指令的示例: 从 Books.xml 文件中删除 XML 处理指令。

参考
下列文件可从 Microsoft 下载中心下载: 立即下载 Books.xml (http://download.microsoft.com/download/...

下列文件可从 Microsoft 下载中心下载:
有关更多信息,请访问以下 Microsoft Web 站点:
.NET 中的 XML:.NET Framework XML Classes and C# Offer Simple, Scalable Data Manipulation(.NET 中的 XML:.NET 框架 XML 类和 C# 提供简单的可缩放的数据操作)R/> http://msdn.microsoft.com/msdnmag/issues/01/01/xml/default.aspx (http://msdn.microsoft.com/msdnmag/issues/01/01/xml/default.aspx)

XPathNavigator Class
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemXmlXPathXPathNavigatorClassTopic.asp (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemXmlXPathXPathNavigatorClassTopic.asp)

XPathDocument Class(XPathDocument 类)
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemXmlXPathXPathDocumentClassTopic.asp (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemXmlXPathXPathDocumentClassTopic.asp)

XPathNodeIterator Class(XPathNodeIterator 类)
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemXmlXPathXPathNodeIteratorClassTopic.asp (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemXmlXPathXPathNodeIteratorClassTopic.asp)

XSLT Transformations with the XslTransform Class(使用 XslTransform 类 的 XSLT 转换)
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconxslttransformationswithxsltransformclass.asp (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconxslttransformationswithxsltransformclass.asp)

XPath Examples(XPath 示例)
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/xmlsdk30/htm/xmrefxpathexamples.asp (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/xmlsdk30/htm/xmrefxpathexamples.asp)

XPath Syntax(XPath 语法)
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/xmlsdk30/htm/xmrefxpathsyntax.asp (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/xmlsdk30/htm/xmrefxpathsyntax.asp)
有关 XPath 的更多信息,请访问下列 WWW 联合会 (W3C) Web 站点:
XML 路径语言 (XPath)
1.0 版:W3C 在 1999 年 11 月 16 日提出的建议
http://www.w3.org/TR/1999/REC-xpath-19991116 (http://www.w3.org/TR/1999/REC-xpath-19991116)

这篇文章中的信息适用于:
  • Microsoft ADO.NET(随 .NET 框架一起提供)
  • Microsoft Visual C# .NET 2002 标准版
关键字: 
kbhowto kbhowtomaster kbdownload KB308333

使用 dom4j 解析 XML(转)

摘自:http://tech.ddvip.com/2008-08/121908667655565.html

dom4j API 包含一个解析 XML 文档的工具。本文中将使用这个解析器创建一个示例 XML 文档。清单 1 显示了这个示例 XML 文档,catalog.xml。

  清单 1. 示例 XML 文档(catalog.xml)

<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<!--An XML Catalog-->
<?target instruction?>
 <journal title="XML Zone"
         publisher="IBM developerWorks">
<article level="Intermediate" date="December-2001">
<title>Java configuration with XML Schema</title>
<author>
   <firstname>Marcello</firstname>
   <lastname>Vitaletti</lastname>
</author>
 </article>
 </journal>
</catalog>

  然后使用同一个解析器修改 catalog.xml,清单 2 是修改后的 XML 文档,catalog-modified.xml。

  清单 2. 修改后的 XML 文档(catalog-modified.xml)

<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<!--An XML catalog-->
<?target instruction?>
 <journal title="XML Zone"
          publisher="IBM developerWorks">
<article level="Introductory" date="October-2002">
<title>Create flexible and extensible XML schemas</title>
<author>
   <firstname>Ayesha</firstname>
   <lastname>Malik</lastname>
</author>
 </article>
 </journal>
</catalog>


 与 W3C DOM API 相比,使用 dom4j 所包含的解析器的好处是 dom4j 拥有本地的 XPath 支持。DOM 解析器不支持使用 XPath 选择节点。

  本文包括以下几个部分:

  预先设置

  创建文档

  修改文档

  预先设置

   这个解析器可以从 http://dom4j.org 获取。通过设置使 dom4j-1.4/dom4j-full.jar 能够在 classpath 中访问,该文件中包括 dom4j 类、XPath 引擎以及 SAX 和 DOM 接口。如果已经使用了 JAXP 解析器中包含的 SAX 和 DOM 接口,向 classpath 中增加 dom4j-1.4/dom4j.jar 。 dom4j.jar 包括 dom4j 类和 XPath 引擎,但是不含 SAX 与 DOM 接口。

  创建文档

  本节讨论使用 dom4j API 创建 XML 文档的过程,并创建示例 XML 文档 catalog.xml。

  使用 import 语句导入 dom4j API 类:

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

  使用 DocumentHelper 类创建一个文档实例。 DocumentHelper 是生成 XML 文档节点的 dom4j API 工厂类。

Document document = DocumentHelper.createDocument();

  使用 addElement() 方法创建根元素 catalog 。 addElement() 用于向 XML 文档中增加元素。

Element catalogElement = document.addElement("catalog");

  在 catalog 元素中使用 addComment() 方法添加注释"An XML catalog"。

catalogElement.addComment("An XML catalog");

  在 catalog 元素中使用 addProcessingInstruction() 方法增加一个处理指令。

catalogElement.addProcessingInstruction("target","text");


在 catalog 元素中使用 addElement() 方法增加 journal 元素。

Element journalElement = catalogElement.addElement("journal");

  使用 addAttribute() 方法向 journal 元素添加 title 和 publisher 属性。

journalElement.addAttribute("title", "XML Zone");
     journalElement.addAttribute("publisher", "IBM developerWorks");

  向 article 元素中添加 journal 元素。

Element articleElement=journalElement.addElement("article");

  为 article 元素增加 level 和 date 属性。

articleElement.addAttribute("level", "Intermediate");
   articleElement.addAttribute("date", "December-2001");

  向 article 元素中增加 title 元素。

Element titleElement=articleElement.addElement("title");

  使用 setText() 方法设置 article 元素的文本。

titleElement.setText("Java configuration with XML Schema");

  在 article 元素中增加 author 元素。

Element authorElement=articleElement.addElement("author");

  在 author 元素中增加 firstname 元素并设置该元素的文本。

Element firstNameElement=authorElement.addElement("firstname");
   firstNameElement.setText("Marcello");

  在 author 元素中增加 lastname 元素并设置该元素的文本。


Element lastNameElement=authorElement.addElement("lastname");
   lastNameElement.setText("Vitaletti");

  可以使用 addDocType() 方法添加文档类型说明。

document.addDocType("catalog", null,"file://c:/Dtds/catalog.dtd");

  这样就向 XML 文档中增加文档类型说明:

<!DOCTYPE catalog SYSTEM "file://c:/Dtds/catalog.dtd">

  如果文档要使用文档类型定义(DTD)文档验证则必须有 Doctype。

  XML 声明 <?xml version="1.0" encoding="UTF-8"?> 自动添加到 XML 文档中。

  清单 3 所示的例子程序 XmlDom4J.java 用于创建 XML 文档 catalog.xml。

  清单 3. 生成 XML 文档 catalog.xml 的程序(XmlDom4J.java)

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.XMLWriter;
import java.io.*;
public class XmlDom4J{
public void generateDocument(){
Document document = DocumentHelper.createDocument();
   Element catalogElement = document.addElement("catalog");
   catalogElement.addComment("An XML Catalog");
   catalogElement.addProcessingInstruction("target","text");
   Element journalElement = catalogElement.addElement("journal");
   journalElement.addAttribute("title", "XML Zone");
   journalElement.addAttribute("publisher", "IBM developerWorks");
   Element articleElement=journalElement.addElement("article");
   articleElement.addAttribute("level", "Intermediate");
   articleElement.addAttribute("date", "December-2001");
   Element titleElement=articleElement.addElement("title");
   titleElement.setText("Java configuration with XML Schema");
   Element authorElement=articleElement.addElement("author");
   Element firstNameElement=authorElement.addElement("firstname");
   firstNameElement.setText("Marcello");
   Element lastNameElement=authorElement.addElement("lastname");
   lastNameElement.setText("Vitaletti");
   document.addDocType("catalog",
              null,"file://c:/Dtds/catalog.dtd");
  try{
  XMLWriter output = new XMLWriter(
      new FileWriter( new File("c:/catalog/catalog.xml") ));
    output.write( document );
    output.close();
    }
   catch(IOException e){System.out.println(e.getMessage());}
}
public static void main(String[] argv){
XmlDom4J dom4j=new XmlDom4J();
dom4j.generateDocument();
}}


 这一节讨论了创建 XML 文档的过程,下一节将介绍使用 dom4j API 修改这里创建的 XML 文档。

  修改文档

  这一节说明如何使用 dom4j API 修改示例 XML 文档 catalog.xml。

  使用 SAXReader 解析 XML 文档 catalog.xml:

SAXReader saxReader = new SAXReader();
Document document = saxReader.read(inputXml);

  SAXReader 包含在 org.dom4j.io 包中。

   inputXml 是从 c:/catalog/catalog.xml 创建的 java.io.File。使用 XPath 表达式从 article 元素中获得 level 节点列表。如果 level 属性值是"Intermediate"则改为"Introductory"。

List list = document.selectNodes("//article/@level" );
   Iterator iter=list.iterator();
    while(iter.hasNext()){
      Attribute attribute=(Attribute)iter.next();
        if(attribute.getValue().equals("Intermediate"))
        attribute.setValue("Introductory");
    }

  获取 article 元素列表,从 article 元素中的 title 元素得到一个迭代器,并修改 title 元素的文本。

list = document.selectNodes("//article" );
   iter=list.iterator();
  while(iter.hasNext()){
    Element element=(Element)iter.next();
   Iterator iterator=element.elementIterator("title");
  while(iterator.hasNext()){
  Element titleElement=(Element)iterator.next();
  if(titleElement.getText().equals("Java configuration with XML Schema"))
   titleElement.setText("Create flexible and extensible XML schema");
  }}


  通过和 title 元素类似的过程修改 author 元素。

  清单 4 所示的示例程序 Dom4JParser.java 用于把 catalog.xml 文档修改成 catalog-modified.xml 文档。

  清单 4. 用于修改 catalog.xml 的程序(Dom4Jparser.java)

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Attribute;
import java.util.List;
import java.util.Iterator;
import org.dom4j.io.XMLWriter;
import java.io.*;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
public class Dom4JParser{
public void modifyDocument(File inputXml){
 try{
  SAXReader saxReader = new SAXReader();
  Document document = saxReader.read(inputXml);
  List list = document.selectNodes("//article/@level" );
  Iterator iter=list.iterator();
  while(iter.hasNext()){
  Attribute attribute=(Attribute)iter.next();
  if(attribute.getValue().equals("Intermediate"))
   attribute.setValue("Introductory");
    }
 
  list = document.selectNodes("//article/@date" );
  iter=list.iterator();
  while(iter.hasNext()){
  Attribute attribute=(Attribute)iter.next();
  if(attribute.getValue().equals("December-2001"))
   attribute.setValue("October-2002");
    }
  list = document.selectNodes("//article" );
  iter=list.iterator();
  while(iter.hasNext()){
  Element element=(Element)iter.next();
  Iterator iterator=element.elementIterator("title");
   while(iterator.hasNext()){
    Element titleElement=(Element)iterator.next();
    if(titleElement.getText().equals("Java configuration with XML
   Schema"))
    titleElement.setText("Create flexible and extensible XML schema");
                     }
                }
  list = document.selectNodes("//article/author" );
  iter=list.iterator();
   while(iter.hasNext()){
   Element element=(Element)iter.next();
   Iterator iterator=element.elementIterator("firstname");
   while(iterator.hasNext()){
   Element firstNameElement=(Element)iterator.next();
   if(firstNameElement.getText().equals("Marcello"))
   firstNameElement.setText("Ayesha");
                   }
               }
  list = document.selectNodes("//article/author" );
  iter=list.iterator();
   while(iter.hasNext()){
   Element element=(Element)iter.next();
   Iterator iterator=element.elementIterator("lastname");
   while(iterator.hasNext()){
   Element lastNameElement=(Element)iterator.next();
   if(lastNameElement.getText().equals("Vitaletti"))
   lastNameElement.setText("Malik");
                 }
                }
   XMLWriter output = new XMLWriter(
   new FileWriter( new File("c:/catalog/catalog-modified.xml") ));
   output.write( document );
   output.close();
  }
 catch(DocumentException e)
         {
         System.out.println(e.getMessage());
              }
 catch(IOException e){
            System.out.println(e.getMessage());
          }
}
public static void main(String[] argv){
 Dom4JParser dom4jParser=new Dom4JParser();
 dom4jParser.modifyDocument(new File("c:/catalog/catalog.xml"));
                    }
  }

  这一节说明了如何使用 dom4j 中的解析器修改示例 XML 文档。这个解析器不使用 DTD 或者模式验证 XML 文档。如果 XML 文档需要验证,可以解释用 dom4j 与 JAXP SAX 解析器。

  结束语

  包含在 dom4j 中的解析器是一种用于解析 XML 文档的非验证性工具,可以与JAXP、Crimson 或 Xerces 集成。本文说明了如何使用该解析器创建和修改 XML 文档。

2008年12月27日星期六

Google搜索质量介绍

摘自:http://www.googlechinablog.com/2008/06/google.html


Udi Manber, 工程事务副总裁,搜索质量

原文:
Introduction to Google Search Quality
发表于:2008 年 5 月 20 日星期二 下午06:20

搜索质量团队是一支负责
Google搜索结果排名的团队。我们的工作非常明确:每天都有数以亿计的人们Google发出搜索请求 Google需要在短短几分之一秒的时间内从数十亿网页中挑选出符合搜索要求的页面,并且以恰当的排序提供给用户。虽然近期我们也在做一些其他工作,但请允许我以后再向您详细介绍。


虽然很多人都在使用Google的搜索服务,但令人吃惊的是很少有人了解Google的搜索排名。这是我们的过错,但实际上我们是有意进行保密的。坦诚布公地说,很大程度上,我们需要对我们所从事的工作保密。这主要有两个原因:竞争和欺诈滥用行为。竞争是很容易理解的。没有哪一家公司愿意与对手分享其核心技术;至于欺诈滥用行为,如果我们将排名算法公布于众,会使这个搜索系统容易被人为操纵。通过保密来保证安全从来都不是最好的办法,所以我们也不完全依赖它,但保密措施也确实帮助我们避免了许多被欺诈滥用的可能。

排名算法的细节从很多方面来说都堪称是Google皇冠上的宝石。我们感到非常自豪也特别注意保护它们。据估计,已有一千多名程序员(科学家)将自己多年的研究成果贡献在它们的发展中,因而它们的创新速度从没有放缓过。

但保持完全神秘并不是理想状态,这篇博客就是我们想要改善此状况的一种努力。我们会努力做到定期向大家介绍新产品,讲解已有产品,提供建议,传播信息,进而增进交流。现在就让我介绍一些关于我们团队的信息,以此作为与大家沟通的开始。更多的博客也将会陆续发布

借此机会我想简单的介绍一下自己。我的名字是Udi Manber,目前担任工程事务副总裁,负责搜索质量的相关工作。我在Google工作已超过两年,在搜索技术方面已经有差不多20年的从业经历。

负责精确排名技术的小组是整个团队的核心。对搜索结果进行排名是很困难的,比一般人想象的要难得多。原因之一是语言本身天然具有模糊性,而记录信息的文档也五花八门,没有一定的法则。目前,还没有一个如何传达信息的统一标准,因此我们需要试图理解任何人以任何理由写出的所有网页。而且,这只是问题的一部分。我们还需要理解人们提出的、平均少于三个单词的搜索提问,并将它们映射到我们对所有网络文档的理解中。更不用说每个人都有不同的需要。我们必须尽最大努力在几毫秒内满足这些需求。

在我们的排名算法中,最有名的部分是 PageRank ,它是由谷歌的两位创始人——LarryPageSergey Brin 开发出来的。目前PageRank仍被使用,只是它已成为了一个更大系统中的一部分。其他部分包括语言模型(处理短语、同义词、符号、拼写错误的能力等),查询模式(我们不仅要考虑语言本身,还要考虑人们如何使用语言),时间模型(有些问题要靠互联网上仅仅产生才三十分钟的最新网页来解答,而另一些问题则需由经受了时间考验的网页来解答),和个性化模式(并不是所有人都想得到同样的答案)。

在我们的团队中,还有一个小组负责评估我们的工作。评估方式有许多种,但目标都是一致的:提高用户体验。这不是主要目标,而是唯一目标。这里既有每分钟都在进行的自动评估(确保系统运行正常),对总体质量的周期性评估,还有更重要的是为具体算法改进而开展的评估,这也是最重要的。当一名工程师有一个新想法或开发出一种新算法时,我们都会对其想法进行全面测试。我们有一个统计小组专门负责统计数据,同时评估这些新想法的价值。我们每周都会(有时甚至一周两次)召开专门会议审议这些新想法并且批准新方案的开展。在2007年,我们共推出了450多个新改进,平均每周推出9个。其中的一些改进是简单而明显的——举例来说,我们解决了希伯来语缩写检索词的问题(在希伯来语中,缩写词是由最后一个字符旁的(")来标识的,因此,IBM的缩写将是IB"M);当然也有一些改进是非常复杂的——举例来说,在一月份我们对PageRank算法做了显著改进。绝大部分时间里我们都在寻求改进搜索结果的相关性,但同时我们也在开展以简化算法为目的的项目。毕竟,简单一些总是好的。

在过去两年中,跨国界搜索一直是我们关注的重点。这意味着我们要精通所有语言,而不仅仅是那些主要的语种。以去年为例,我们在阿塞拜疆语上取得了重大进展,而这种语言世界上仅有800万人在使用。在过去几个月,我们进行了多种语言的拼写检查,包括爱沙尼亚语,加泰罗尼亚语,塞尔维亚语,塞尔维亚克罗地亚语,乌克兰语,波斯尼亚语,拉脱维亚语,菲律宾他加禄语,斯洛文尼亚和波斯语。我们建立了一个遍布全球的网络体系来为我们提供反馈意见,同时还有来自Google全球各部分的讲不同语言的员工自愿帮助我们改进搜索结果。

还有一个小组是专门致力于对搜索特性和用户界面的改进。一个强大的引擎对于一辆好汽车是非常必要的,但并不是足够的。好车还要舒适和易于驾驶。 Google的搜索用户界面非常简洁,很少有用户曾经浏览过搜索帮助页面,因为不借助它用户也能使用得得心应手(但是阅读这些帮助页面总是有益的,而且我们一直在努力完善它们)。当我们添加新特性时,我们会努力确保它们具有直观性并且易于每个人使用。过去一年中,我们做的最明显的变化是整合搜索。其他变化还包括谷歌笔记本(Google Notebook)自定义搜索引擎(Custom Search Engine),当然还包括在iGoogle上的改进 。用户界面小组由一个专门负责进行用户研究和评估新特性的专家团队组成。他们的足迹遍布世界各地,有时甚至到用户的家中去了解他们最自然的使用习惯。 (不过不用担心,他们是不会搞突然袭击或是不请自来的 !)

我们还有一个小组专门负责与网络垃圾和各种类型的欺诈滥用行为作斗争。他们处理的问题非常广泛:从隐藏文本到充斥大量无用关键词而偏离主题的网页,以及其他许多旨在提高搜索结果排名的恶意行为。这个小组密切跟踪网络垃圾的最新发展趋势并研究出行之有效的对策;与所有其他小组一样,他们的工作也是国际性的。反网络垃圾小组与Google网站管理员中心小组紧密合作,从而能与大家分享他们的心得,并听取网站管理员们的意见。

还有其他一些小组投身于其他的专门项目。总之,我们的组织结构是比较非正式的。人员具有灵活性,新项目随时都有可能开始。

对于搜索,其中很关键的一点就是用户的期望始终在快速增长。明天的检索查询要比今天的更具挑战性。就像运算速度受摩尔定律支配,每18个月要成倍增长一样,搜索中也有一个隐形的规律,那就是最难的那部分搜索查询其复杂性在短时间内就会成倍增加,变得更为复杂。这是不可能进行精确衡量的,但我们都能亲身感受到。我们知道自己不能总停留在现有状态上,我们必须努力工作,迎接挑战。正如我刚才所说的,在未来几个月中我们将继续为您提供搜索质量改进的最新消息,敬请关注。