2011-09-23 25 views
4

的缩写谁能解释什么是的XPath - position()函数

/root/a[position()=1 or position()=2 

/root/a[1 or 2] 

之间的区别? 我假设第二个是第一个的缩写形式,但是Java XPath(Sun JDK 1.6.0)处理器认为不然。以下是我的测试应用程序。

libxml2库和db2 XPath处理器也认为这些路径不同。所以它看起来不像JDK的bug。

import java.io.*; 
import javax.xml.xpath.*; 
import org.w3c.dom.*; 

import org.xml.sax.InputSource; 

public class XPathTest { 
    public static void main(String[] args) throws Exception { 
     //String xpathStr = "/root/a[position()=1 or position()=2]"; 
     String xpathStr = "/root/a[1 or 2]"; 

     XPathFactory xpf = XPathFactory.newInstance(); 
     XPath xp = xpf.newXPath(); 
     Reader irdr = new StringReader(
       "<root><a name=\"first\"/><a name=\"second\"/><a name=\"third\"/></root>"); 
     InputSource isrc = new InputSource(irdr); 
     XPathExpression expr = xp.compile(xpathStr); 
     Object result = expr.evaluate(isrc, XPathConstants.NODESET); 
     NodeList nodes = (NodeList) result; 
     for (int i = 0; i < nodes.getLength(); i++) { 
      Node node = nodes.item(i); 
      Element element = (Element) node; 
      System.out.print(element.getNodeName() + " " + element.getAttributeNode("name")); 
      System.out.println(); 
     } 
    } 
} 
+0

我猜@安顿不会回来,但如果他确实应该将[生锈的答案](http://stackoverflow.com/a/7525994/539490)标记为正确 – AJP

回答

0

[1 or 2]计算为在.net中的 “总是为真” 谓词一样,所以这种行为似乎是一致的:

下面是一个.NET 3.5的XmlDocument

// Returns first, second 
    var ndl = dom.SelectNodes(@"/root/a[position()=1 or position()=2]"); 

    // Returns first, second and third 
    ndl = dom.SelectNodes(@"/root/a[1 or 2]"); 

    // Returns first, second 
    ndl = dom.SelectNodes(@"/root/a[1] | /root/a[2]"); 
一中的XPath输出

编辑

在XPath 2,你可以使用sequence functionsindex-ofexists确定给定的位置是否被包含在一个值序列:

/root/a[exists(index-of((1,2), position()))] 
+0

这与我的发现一致,但不会不解释为什么1或2有时被视为布尔值,有时被视为数字。 – Anton

4

我不认为[1 or 2]正在评估您怎么看它正在评估。 or适用于两个布尔值。我怀疑12评估为真实。因此,这个表达式被评估为真实的,基本上什么也不做,并且会返回所有的元素。

一般而言,position()可用于像[position() <= 5]这样的表达式中,而索引地址只能选择一个元素,如[5]

+0

如果'1'或'2'用作'或'运算符的参数时总是计算为真,为什么在被'[]'使用时有时计算为假(例如/ root /路径不存在文件)? – Anton

+1

@Anton:在这种情况下,它仍然计算为“true()”,但是它必须过滤掉的节点集是空的节点集。 –

0

[]中的数值被视为索引。 OR不适用于像您的方式索引([1 or 2])。正确的方法是使用position()

+0

我不确定。我的理解是,总是被认为是布尔表达式的内容(所谓的谓词)。如果在那里找到整数(例如'i'),它会扩展为布尔表达式,如 – Anton

+0

...扩展为布尔表达式,如[position()= i] – Anton

+0

我还没有太熟练的使用注释marku。再试一次:-) 我不确定。我的理解是,总是被认为是布尔表达式的内容(所谓的谓词)。如果在那里找到整数(例如'i'),它将扩展为布尔表达式,如'[position()= i]'然后进行评估。 – Anton

1

如果方括号中的值是数字[N],则它被解释为[position()=N]。但[1 or 2]不是一个数字,所以此规则不适用。