3. 使用XPath语法来查询对象和集合
Commons JXPath是一种让人很吃惊地(非标准的)对XML标准的使用。XPath一段时间以来一直是作为在一个XSL样式表中选择结点或结点集的一种方法。如果你用过XML,你会很熟悉用这样的语法/foo/bar来从foo文档元素中选择bar子元素。
Jakarta Commons JXPath增加了一种有趣的手法:你可以用JXPath来从bean和集合中选择对象,其中如servlet上下文和DOM文档对象。考虑一个包含了Person对象的列表。每一个Person对象有一个属性的类型为Job,每一个Job对象有一个salary(薪水)属性,类型为int。Person对象也有一个coountry属性,它是两个字符的国家代码。使用JXPath,你可以很容易地选出所有国家为美国,薪水超过一百万美元的Person对象。下面是设置一个由JXPath过滤地bean的List的代码:
// Person的构造器设置姓和国家代码
Person person1 = new Person( "Tim", "US" );
Person person2 = new Person( "John", "US" );
Person person3 = new Person( "Al", "US" );
Person person4 = new Person( "Tony", "GB" );
// Job的构造器设工作名称和薪水
person1.setJob( new Job( "Developer", 40000 ) );
person2.setJob( new Job( "Senator", 150000 ) );
person3.setJob( new Job( "Comedian", 3400302 ) );
person4.setJob( new Job( "Minister", 2000000 ) );
Person[] personArr = new Person[] { person1, person2, person3, person4 };
List people = Arrays.asList( personArr );
people List包含了四个bean: Tim, John, Al, 和George。Tim是一个挣4万美元的开发者,John是一个挣15万美元的参议员,Al是一个挣340万美元的喜剧演员,Tony是一个挣200万欧元的部长。我们的任务很简单:遍历这个List,打印出每一个挣钱超过100百万美元的美国公民的名字。记住people是一个由Person对象构成的ArrayList,让我们先看一下没有利用JXPath便利的解决方案:
Iterator peopleIter = people.getIterator();
while( peopleIter.hasNext() ) {
Person person = (Person) peopleIter.next();
if( person.getCountry() != null &&
person.getCountry().equals( "US" ) &&
person.getJob() != null &&
person.getJob().getSalary() > 1000000 ) {
print( person.getFirstName() + " " + person.getLastName() );
}
}
}
}
上面的例子是繁重的,并有些容易犯错。为了发现合适的Person对象,你必须首先遍历每一个Person对象并且检查conuntry的属性。如果country属性不为空并且符合要求,那么你就要检查job属性并看一下它是否不为空并且salary属性的值大于100万。上面的例子的代码行数可以被Java 1.5的语法大大减少,但是,哪怕是Java 1.5,你仍旧需要在两层上作两次比较。
如果你想对内存中的一组Person对象也做一些这样的查询呢?如果你的应用想显示所有在英格兰的名叫Tony的人呢?喔,如果你打印出每一个薪水少于2万的工作的名称呢?
如果你将这些对象存储到关系数据库中,你可以用一个SQL查询来解决问题,但你正在处理的是内存中的对象,你可以不必那么奢侈。虽然XPath主要是用在XML上面,但你可以用它来写一个针对对象集合的“查询”,将对象作为元素和,把bean属性作为子元素。是的,这是一种对XPath奇怪的应用,但请先看一下下面的例子如何在people上,一个由Person对象构成的ArrayList,实现这三种查询:
import org.apache.commons.jxpath.JXPathContext;
public List queryCollection(String xpath, Collection col) {
List results = new ArrayList();
JXPathContext context = JXPathContext.newContext( col );
Iterator matching = context.iterate( xpath );
while( matching.hasNext() ) {
results.add( matching.getNext() );
}
return results;
}
String query1 = ".[@country = 'US']/job[@salary > 1000000]/..";
String query2 = ".[@country = 'GB' and @name = 'Tony']";
String query3 = "./job/name";
List richUsPeople = queryCollection( query1, people );
List britishTony = queryCollection( query2, people );
List jobNames = queryCollection( query3, people );
queryCollection()方法使用了一个XPath表达式,将它应用到一个集合上。XPath表达式被JXPathContext求值, JXPathContext由JXPathContext.newContext()调用创建,并将它传入要执行查询的集合中。凋用context.iterate()来在集合中的每一个元素上应用XPath表达式,返回包含所有符合条件的“节点”(这里是“对象”)的Iterator。上例中执行的第一个查询,query1,执行了和不使用JXPath的例子相同的查询。query2选择所有国家为GB并且名字属性为Tony的Person对象,query3返回了一个String对象的List,包含了所有Job对象的name属性。
当我第一次看到Commons JXPath, 它是一个坏思想的想法触动了我。为什么要把XPath表达式应用到对象上?有点感觉不对。把XPath作为一个bean的集合的查询语言的这种意想不到的用法,在过去几年中已经好多次给我带来了便利。如果你发现你在list中循环来查找符合条件的元素,请考虑一下JXPath。更多的信息,请参考Jakarta Commons Cookbook的第12章,“查找和过滤”,它讨论了Commons JXPath和与Commons Digester配对的Jakarta Lucene。
分享到:
相关推荐
jakarta commons cookbook 电子版很实用
介绍了Apache Jakarta Commons 项目下Java组件,如FileUpload, HttpClient, DBCP,BeanUtils,Logging,Lang, 以及 Collections,Codec等,是学习和使用Apache Jakarta Commons良好的参考使用手册。
jakarta-commons 相关依赖包,文件列表: commons-attributes-api.jar commons-attributes-compiler.jar commons-beanutils.jar commons-codec.jar commons-collections.jar commons-dbcp.jar commons-digester.jar ...
Jakarta Commons组件之commons-lang-2.3-src.zip
jakarta commons-logging 1.1.1
Jakarta Commons Cookbook
Jakarta Commons Online Bookshelf.Mar.2005
jakarta commons的API
本书是一本介绍apache commons使用的电子书
Jakarta Commons FileUpload 用户指南
Jakarta Commons-lang API & Source Code Jakarta lang包API帮助文档,并带有源码
Jakarta commons docs API CHM 格式带索引和全文搜索,方便携带和查询。 Jakarta commons 包含很多可复用的通用组件。 commons-attributes 让开发者可以使用 C# 或 .net 样式的 attributes, 是一种运行时的 api, ...
Jakarta Commons使用,方便自己看看的东西。。
jakarta_commons_io jakarta_commons_io
jakarta commons cookbook java开发的工具字典。相当实用。
博文链接:https://dcriori.iteye.com/blog/127788
COMMONS的介绍,关于基本信息和某些类的使用方法
了解Apacche的Jakarta Commons库
Jakarta+Commons中文介绍 org.apache.commons包的中文介绍,学习
jar包jakarta-taglibs-standard-1.1.2和commons-fileupload-1.3.2和commons-io-2.5