XPath中如何比较不同类型的对象

王朝c#·作者佚名  2006-12-17
窄屏简体版  字體: |||超大  

目前XPath2.0还没有正式定稿,因此本文的讨论是基于XPath1.0.

XPath支持四种基本类型:

1. Node-set

2. string

3. number

4. boolean

我们知道一个Location Step由Axis,Node Test和Predicate三部分组成,而用于查询XML文档的XPath又是由若干Location Step组成,比如/table/row[id='0000']。在Predicate中几乎总是需要运用=,!=,<,<=,<=进行比较。而对于不同的对象如何进行比较,尤其是涉及到node-set的比较却是十分容易使人困惑。比如对下面文档进行Root/Numbers[Integer/@value > 4]<Root>查询。

<Numbers>

<Integer value="4" />

<Integer value="2" />

<Integer value="3" />

</Numbers>

<Numbers>

<Integer value="2" />

<Integer value="3" />

<Integer value="6" />

</Numbers>

</Root>

下面我以伪代码的形式解释XPath中是如何比较不同对象的。其中compareObjects涉及到

boolean compareObjects(Object operand1,Object operand2,String operator)throws Exception{

//both objects to be compared are node-sets

if(both operand1 and operand2 are node-sets){

Iterator i1 = operand1.iterator();

Iterator i2 = operand2.iterator();

while((node1 =i1.next()!=null){

while((node2 =i2.next()!=null){

//convert node1 and node2 to string values

String s1 = (String)node1;

String s2 = (String)node2;

if(compareBasic(s1,s2,operator))return true;

}

}

//neither object to be compared is a node-set

}else if(neither operand1 nor operand2 is node-set){

return compareBasic(operand1,operand2,operator);

}else{

//In this case, one object is node-set and the other is of basic type.Assume operand1 is node-set

Iterator i1 = operand1.iterator();

while((node1 =i1.next()!=null){

if(operand2 is number)convert node1 to number as a new object named newOperand1

if(operand2 is string)convert node1 to string as a new object named newOperand1

if(operand2 is boolean)convert node1 to boolean as a new object named newOperand1

if(compareBasic(newOperand1,operand2,operator))return true

}

}

return false

}

boolean compareBasic(Object operand1, Object operand2, String operator) throws Exception{

if (operator is "<=" or "<" or ">=" or ">"){

convert operand1 and operand2 to number

compare the two numbers with the operator;

}else if("=".equals(operator)||"!=".equals(operator)){

if(at least one object is boolean){convert the other object to boolean}

if(at least one object is number){convert the other object to number}

if(at least one object is string){convert the other object to string}

compare the new two objects with "=" or "!="

}else{

throw new Exception("Doesn’t support this operator!");

}

}

根据上述算法,该查询就是选择文档中的所有 <Numbers> 元素,其中“至少一个”<Integer> 元素具有值大于 4 减 1 的 value 属性。查询结果应该是:

<Numbers>

<Integer value="4" />

<Integer value="2" />

<Integer value="3" />

</Numbers>

<Numbers>

<Integer value="2" />

<Integer value="3" />

<Integer value="6" />

</Numbers>

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
© 2005- 王朝網路 版權所有 導航