JXPath使用实例

为了演示的目的,我们采取了一个相对简单的模型:一个公司有多个部门,一个部门有多个员工,下面是模型图:


[img]http://dl2.iteye.com/upload/attachment/0094/8827/13165d0e-0663-3bd8-9854-56bcca4d3728.jpg[/img]

执行简单的JXPath 查询:

  最简单的查询就是从对象树中查找一个对象,例如,要查找公司,用下面的代码:

JXPathContext context = JXPathContext.newContext(company);
Company c = (Company)context.getValue(".");

  第一行展示了context (上下文)的创建,也就是对象树中所有JXPath的xpath 规则的起始点(相当于XML文档的根节点元素)。

  第二行执行了实际的查询,因为这里的上下文是以公司开始的,所以要获取公司对象,只需要使用当前元素选择器“.”。

  使用谓词和变量

  一个员工是部门的子对象,获取员工名为johnny 的代码如下:

Employee emp = (Employee)context.getValue("/departmentList/employees[name='Johnny']");


  这段代码可以这样理解:遍历所有的部门寻找姓名为johnny的员工

  上面的代码段解释了如何使用谓词进行对象的搜索,使用谓词相当于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 提供了一个迭代器,可以对查询的结果进行迭代,下面的代码:

for(Iterator iter = context.iterate("/departmentList");iter.hasNext();)
...
{
Department d = (Department)iter.next();
//...
}


  迭代所有员工的代码如下:

for(Iterator iter = context.iterate("/departmentList/employees"); 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();
//
}


指针 Pointers

  指针是JXPath的一个工具类,用来代表对象树中的一个对象的引用,比如,一个指针可能代表了第二个部门的第一个员工,相比于直接从对象树中查找对象的对象,指针提供了一些额外的功能,比如在相关上下文下的相关查询,下面有具体的例子:

  使用指针

  使用指针指向一个对象和从对象树中获取一个对象是相等的:

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();
JXPathContext relativeContext = context.getRelativeContext(empPtr);
}

  使用相关上下文,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 语言 进行查询,因此有大量的资料可以帮助构建高效的复杂对象树查询,指针和相关上下文的加入使得查询更加方便。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用dom4j获取节点的完整路径和对应的行号时,你可以使用XPath表达式和节点的Location Path。 首先,使用XPath表达式来获取节点的完整路径。XPath表达式是一种用于在XML文档中定位节点的语言。在dom4j中,你可以使用`XPath`类来执行XPath表达式。假设你要获取名为`node`的节点的完整路径,可以按照以下步骤进行: 1. 创建一个`Document`对象,表示你的XML文档。假设你的XML文档已经被解析为`Document`对象,并且存储在变量`document`中。 2. 创建一个`XPath`对象,并使用XPath表达式来指定要获取的节点。例如,对于名为`node`的节点,可以使用XPath表达式`//node`。 ```java XPath xpath = DocumentHelper.createXPath("//node"); ``` 3. 使用`evaluate()`方法执行XPath表达式,并传入`document`作为参数。这将返回一个节点列表。 ```java List<Node> nodeList = xpath.evaluate(document); ``` 4. 遍历节点列表,并使用`getPath()`方法获取每个节点的完整路径。 ```java for (Node node : nodeList) { String path = node.getPath(); System.out.println("Node path: " + path); } ``` 接下来,获取对应节点的行号。dom4j提供了一个`Dom4jXPath`类,可以在执行XPath表达式时获取节点的行号。你可以按照以下步骤进行: 1. 导入`Dom4jXPath`类。 ```java import org.dom4j.io.Dom4jXPath; ``` 2. 创建一个`Dom4jXPath`对象,并使用XPath表达式来指定要获取的节点。例如,对于名为`node`的节点,可以使用XPath表达式`//node`。 ```java Dom4jXPath xpath = new Dom4jXPath("//node"); ``` 3. 使用`setDocument()`方法将`document`对象设置为`Dom4jXPath`对象的文档。 ```java xpath.setDocument(document); ``` 4. 使用`selectNodes()`方法执行XPath表达式,并传入`document`作为参数。这将返回一个节点列表。 ```java List<Node> nodeList = xpath.selectNodes(document); ``` 5. 遍历节点列表,并使用`getLineNumber()`方法获取每个节点的行号。 ```java for (Node node : nodeList) { int lineNumber = node.getLineNumber(); System.out.println("Node line number: " + lineNumber); } ``` 通过以上步骤,你可以使用dom4j获取节点的完整路径和对应的行号。记得替换掉代码中的`//node`为你实际需要获取的节点的XPath表达式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值