`
cleverpig
  • 浏览: 150094 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

使用JXPath查询Java对象

阅读更多
使用JXPath查询Java对象
—使用XPath表达式语言查询复杂的Java对象树


译者:cleverpig
原文作者:Bart van Riel
原文出处:http://www.javaworld.com/javaworld/jw-03-2007/jw-03-jxpath.html

         在近期的一个项目中,我需要一种能够遍历Java对象树并从中提取对象属性值的简单方法。我希望找到一种提供 “我所想要的id为X并且具有属性A的对象”的简单工具,来顶替传统的不优雅方式——通过巨大的if-else迭代器设置对对象树进行不断地遍历。         

        而JXPath正是我想找的那种对象查询工具。它是一个Apache公用组件:使用众所周知的XPath表达式语言,能够对复杂的对象树进行查询。因此我将JXPath广泛地用在项目中,并且由于通过它的值提取算法(value-extraction algorithms)使应用获得了很大程度上的加速。        

        但是,JXPath并没有被广泛地文档化。因为我正在深度探索此组件,所以我决定将我的发现写到一个内容详实的JXPath入门中,这个入门可以在我的站点上找到。本文是这个入门的精简版本,它可以帮助你快速上手。        
                        
        注意:你可以从相关资源中下载本文的示例代码。

示例模型

        为了利用展示的目的,我们将使用一个简单的模型:一个具有多个部门(department)的公司(company),其中每个部门有多个雇员(employee)。下面是类模型:
image
Company类结构图
        很自然,我们需要一些用于该模型的样本数据:image

         一切就绪了,现在就让我们开始使用JXPath吧!

执行简单的JXPath查询

        最简单的查询就是从对象树中提取单一对象。例如,为了取出Company对象,我们将使用到如下代码:
JXPathContext context = JXPathContext.newContext(company);
Company c = (Company)context.getValue(".");

         第一行展示了如何建立一个上下文(context),它是对象树中所有JXPath的Xpath表达式的起点(与XML文档中的根节点类似)。第二行代码 执行了实际的查询。由于我们的上下文从company层开始,所以为了获取Company对象,我们简单地使用当前成员选择器“.”。

使用判定(predicate)和变量        

        Employee是Department的子对象。为了获取名为“Johnny”的Employee对象使用如下代码(注意此时Company仍然是上下文的起点):
Employee emp = (Employee)context.getValue("/departmentList/employees[name='Johnny']");

        代码大意为:“从起点开始查询所有Department中name属性值为Johnny俄Employee对象”。

        上面的代码说明了如何通过使用特定值来利用判定进行对象查询。判定的用法类似在SQL中使用WHERE子句。我们甚至能够将多个判定合并在一个查询中:
Employee emp = 
   (Employee)context.getValue("/departmentList/employees[name='Susan' and age=27]");


        除非使用特定的、一次性的查询,使用硬编码的查询通称是不合理的。最好定义一个能够使用不同参数执行的、可重用的查询。为了提供这种参数化的查询,JXPath支持在查询中使用变量。下面是使用变量的代码示例:
context.getVariables().declareVariable("name", "Susan");
context.getVariables().declareVariable("age", new Integer(27));
Employee emp =
   (Employee)context.getValue("/departmentList/employees[name=$name and age=$age]");


在集合上进行迭代

        JXPath能够提供作用于查询获取的所有对象的迭代器,就像SQL中迭代结果集一样。下面的代码片段展示了如何对所有的Department进行迭代:
for(Iterator iter = context.iterate("/departmentList"); iter.hasNext();){
   Department d = (Department)iter.next();
   //...
}

        获取所有Department的所有Employee并进行迭代:
for(Iterator iter = context.iterate("/departmentList/employees"); iter.hasNext();){
   Employee emp = (Employee)iter.next();
   //...
}

        为了取得在销售部门的所有年龄大于30岁的Employee:
 for(Iterator iter = context.iterate
     ("/departmentList[name='Sales']/employees[age>30]"); iter.hasNext();){
   Employee emp = (Employee)iter.next();
   //...
}


        使用变量的示例:
context.getVariables().declareVariable("deptName", "Sales");
context.getVariables().declareVariable("minAge", new Integer(30));
for(Iterator iter = context.iterate("/departmentList
     [name=$deptName]/employees[age>$minAge]"); iter.hasNext();){
   Employee emp = (Employee)iter.next();
   //...
}

        以上的两个代码片段展示了多种在XPath查询中的使用判定的方式。

指针        

        指针是一个JXPath工具对象,它代表了在对象树中对对象位置的引用。例如,指针可以指向“第二个department中的第一个employee”。与直接从对象树中获取对象相比,指针提供了通过相关上下文执行相关查询的功能。

使用指针

        使用指向对象树中某个对象的指针几乎和直接获取对象的编码都很简单:
JXPathContext context = JXPathContext.newContext(company);
Pointer empPtr = context.getPointer("/departmentList[name='Sales']/employees[age>40]");

System.out.println(empPtr);
//output: /departmentList[1]/employees[1]

System.out.println(((Employee)empPtr.getValue()).getName());
//output: Johnny

        请注意这里指针的输出展示了指针表示了对象的位置,而不是对象本身。也要注意指针指向的实际对象可以通过指针的getValue()方法获得。

        指针也具有迭代器:
for(Iterator iter = context.iteratePointers("/departmentList[name='Sales']
     /employees[age>30]"); iter.hasNext();){
   Pointer empPtr = (Pointer)iter.next();
   //...
}


相对上下文和相对查询

         由于指针表示了对象的位置,所以它能够被用作在整个对象树中进行“航行”的参考点。为了实现这一点,将指针作为被称为“相对上下文”的根对象(还记得起在 前面示例中使用Company作为根节点吗?)。从这个相对上下文出发,你可以通过通过执行相对查询来对整个对象树进行查询。指针提供的这一优势为查询提 供了很大灵活性,下面将举例说明。

        首先,这是建立相对上下文的方式:
for(Iterator iter = context.iteratePointers("/departmentList[name='Sales']
     /employees[age>30]"); iter.hasNext();){
   Pointer empPtr = (Pointer)iter.next();
   JXPathContext relativeContext = context.getRelativeContext(empPtr);
}

        在这段代码中,为连续的employee指针建立了一个新的相对上下文。
        通过使用相对上下文,XPath能够在整个对象树上兄弟节点、子节点、父节点、祖父节点对象上执行查询:
//Current employee
Employee emp = (Employee)relativeContext.getValue(".");

//Employee name
String name = (String)relativeContext.getValue("./name");

//Name of the Department this Employee belongs to (a parent object)
String deptName = (String)relativeContext.getValue("../name");

//Name of the Company this Employee belongs to (a 'grandparent' object)
String compName = (String)relativeContext.getValue("../../name");

//All coworkers of this Employee (sibling objects)
for(Iterator empIter = relativeContext.iterate("../employees"); empIter.hasNext();){
   Employee colleague = (Employee)empIter.next();
   //...
}


总结

        JXPath是一种用于遍历、查询复杂对象树,并在其中进行“航行”的极其有用的工具。因为它将XPath表达式语言用于查询,因此大量关于XPath的参考资料有助于你建立高效、复杂的对象查询。甚至可以通过使用指针和相对上下文来增加更多的灵活性。

        本文仅仅蜻蜓点水式地涉及到了JXPath的几个可能的方面,如果要获得更多的使用示例和深度的讨论,请阅读我写的完整的入门

作者经历
image
        Bart van Riel已经涉足Java和面向对象时间达七年多了。他即是一位开发者又是一位面向对象和Java领域的培训师。目前他作为软件架构师和开源倡导者任职于全球IT咨询公司Capgemini

相关资源

        下载本文源代码
        Bart van Riel编写的完整的JXPath入门
        Apache Commons JXPath
        W3C提供的XPath入门
分享到:
评论
1 楼 beer2008cn 2011-12-19  
看起来很不错的东西,楼主介绍的也很好,通俗易懂

相关推荐

    jxpath与内存索引

    通过使用JXPath,开发者可以方便地遍历和操作Java对象的属性,就如同在XML文档中使用XPath查询元素一样。 **二、JXPath工作原理** JXPath的工作原理基于Java反射API,它可以解析Java对象的结构,并根据指定的路径...

    commons-jxpath-1.3.jar.zip

    "jxpath"则代表Java XPath API,这是一个用于在Java对象模型(如JavaBeans或XML DOM)中导航的库,它使用XPath表达式来查找、修改和评估节点。 **Apache Commons JXPath** Apache Commons JXPath是Apache Commons...

    jxpath jar包

    jxpath jar包 JXPATH是通过简单的表达式,可以在JAVA的类对象层次中进行查询

    apache-commons源码及jar文件

    Commons-Digester 是一个 XML-Java对象的映射工具,用于解析 XML配置文件. Discovery Commons-Discovery 提供工具来定位资源 (包括类) ,通过使用各种模式来映射服务/引用名称和资源名称。. EL Commons-EL 提供在...

    apache-common最全的jar包

    5. **commons-jxpath-1.3.jar**: JXPath 是一种基于 XPath 的 API,用于在 Java 对象树中导航,可以方便地获取和设置对象属性,特别适用于 XML 数据的操作和解析。 6. **commons-configuration-1.6.jar**: 提供了...

    jqgrid and java

    - `commons-jxpath.jar`:Apache Commons JXPath提供了一种通过路径表达式在Java对象树中导航的方式。 - `commons-lang.jar`:Apache Commons Lang是Java语言功能的补充,包含各种实用工具类。 - `commons-beanutils...

    apache jars

    Commons JXPath提供了使用XPath语法来操作Java对象的功能。这使得开发者能够通过表达式选取和修改Java对象的数据,类似于XML文档中的操作。 6. **Commons Logging**: 这是一个轻量级的日志接口,为不同的日志...

    Java jar包

    9. **Apache Commons JXPath**: 提供了基于路径表达式的Java对象导航工具,类似于XML的XPath。 10. **Apache Commons CLI**: 用于处理命令行接口,简化命令行参数的解析和验证。 在Java项目中,通过引入这些jar包...

    tomcat类包中的一个

    “commons-jxpath-1.3”是Apache Commons JXPath项目的一个版本,该项目是Apache软件基金会的一个子项目,提供了一种使用路径表达式在Java对象图上进行导航的方法,类似于XML中的XPath。JXPath允许开发者以声明性...

    apache web组件使用

    - **JXPath**:使用XPath表达式在Java对象模型(如Map和JavaBean)中导航和修改数据。 3. **工具组件**: - **BeanUtils**:提供JavaBean属性的便捷操作,如复制属性、反射调用方法。 - **Logging**:提供了一种...

    commons jar

    4. **commons-jxpath-1.3.jar**:Apache Commons JXPath允许在Java对象模型上执行XPath表达式。这个1.3版本支持对Java Bean、Map、XML文档和其他可遍历结构的操作。 5. **commons-betwixt-0.8.jar**:Apache ...

    java工具类

    26. **Apache Commons Jxpath**:基于XPath的Java对象导航工具。 27. **Apache Commons Codec**:编码和解码工具,如URL编码、Base64编码等。 28. **Apache Commons Codec**:再次提及,因为它在处理二进制和文本...

    XML_dom4j_解析器 jar包

    1. **加载XML文档**:使用`DocumentFactory`创建`DocumentBuilder`,然后使用`parse()`方法读取XML文件并构建`Document`对象。 ```java DocumentFactory factory = DocumentFactory.getInstance(); DocumentBuilder...

    Jakarta commons docs API CHM 格式

    commons-jxpath 定义了一个简单的XPath表达式语言的解析器.JXPath应用XPath表达式来操纵各种类型的对象包括:JavaBeans,Maps,Servlet contexts,DOM等 commons-lang commons的基础包 commons-launcher 提供多平台的 ...

    比较全面的:Jakarta-commons jar包(附: chm参考手册 & 资源简介)

    commons-jxpath 定义了一个简单的XPath表达式语言的解析器.JXPath应用XPath表达式来操纵各种类型的对象包括:JavaBeans,Maps,Servlet contexts,DOM等 commons-lang commons的基础包 commons-launcher 提供多平台的 ...

    commons常用jar包

    12. **Commons JXPath**: 提供了基于XPath的Java对象导航和操作,可以用于查询和修改Java对象结构。 13. **Commons Zip**: 正如压缩包子文件名所示,这个库用于处理ZIP文件,包括创建、读取、写入和更新ZIP档案。 ...

    Jakarta Commons Online Bookshelf

    JXPath是用于在XML文档中执行路径表达式查询的工具,而Betwixt则是一种将Java对象映射到XML文档的框架。这两个组件结合使用,可以高效地实现XML数据的读取、写入和转换,特别是在XML与Java对象之间的双向转换场景中...

    commons包介绍1

    18. **JXPath**: Commons-JXPath允许使用XPath语法来操作JavaBeans和其他对象,提供了强大的数据导航能力。 19. **Lang**: Commons-Lang提供了许多对`java.lang`包中类的扩展,包括字符串处理、日期时间操作、数组...

    JAKARTA COMMONS

    12. **Commons Digester**: 使用 XML 配置文件映射到 Java 对象,简化 XML 解析和对象创建过程。 13. **Commons Discovery**: 提供工具定位资源,通过模式匹配服务/引用名称和资源名称。 14. **Commons EL**: 提供...

    apache commons笔记1

    16. **JXPath**:提供了使用 XPath 语法操作 JavaBeans 的工具,支持 Java 对象的各种导航和修改。 17. **Lang** 包:包含了很多通用工具类,补充了 `java.lang` 包的功能,如字符串操作、数组处理、日期时间操作等...

Global site tag (gtag.js) - Google Analytics