带有not()和ends-with()的Xpath错误

我有以下Xpath表达式:

//*[not(input)][ends-with(@*, 'Copyright')] 

我希望它能给我所有元素 – 输入除外 – 任何以“Copyright”结尾的属性值。

我使用webDriver.findElements(By.xpath(expression))在Selenium 2 Java API中执行它并获得以下错误:

表达式不是法律表达

但这些表达没有问题:

 //*[not(input)][starts-with(@*, 'Copyright')] //*[ends-with(@*, 'Copyright')] 

有任何想法吗?

我有以下Xpath表达式:

 //*[not(input)][ends-with(@*, 'Copyright')] 

我希望它能给我所有元素 – 输入除外 – 任何以“Copyright”结尾的属性值。

这里有一些问题

  1. ends-with()只是一个标准的XPath 2.0函数,所以你可能正在使用XPath 1.0引擎并且它正确引发错误,因为它不知道一个名为ends-with()的函数。

  2. 即使您使用的是XPath 2.0处理器,表达式ends-with(@*, 'Copyright')在一般情况下也会导致错误,因为ends-with()函数被定义为接受最多一个字符串( xs:string? )作为它的两个操作数 – 但是当元素具有多个属性时, @*会生成一个包含多个字符串的序列。

  3. //*[not(input)]并不意味着“选择所有未命名input元素。真正的含义是:”选择所有没有名为“input”的子元素的元素。

方案

  1. 使用此XPath 2.0表达式: //*[not(self::input)][@*[ends-with(.,'Copyright')]]

  2. 在XPath 1.0的情况下使用此表达式:

….

  //*[not(self::input)] [@*[substring(., string-length() -8) = 'Copyright']] 

以下是使用XSLT对上一个XPath表达式的简短而完整的validation:

        

当此转换应用于以下XML文档时:

      

产生了想要的正确结果

  

如果XML文档位于默认命名空间中

        

应用于此XML文档时

      

产生了想要的正确结果:

  

我不知道Selenium但是如果//*[not(input)][starts-with(@*, 'Copyright')]被成功解析,如果另外XPath 2.0函数ends-with那么我不支持看到任何原因//*[not(input)][ends-with(@*, 'Copyright')]不被接受为合法表达。 然而,你的口头描述听起来好像你想要//*[not(self::input)][@*[ends-with(., 'Copyright')]]

//*[not(input)]选择任何没有任何输入子元素的元素,而//*[not(self::input)]选择任何不是自身input元素的元素。 至于比较[@*[ends-with(., 'Copyright')]]和你所拥有的,我的建议是正确的,只要有任何属性节点以’Copyright’结尾,而你的测试只有在那里工作是一个以’Copyright’结尾的单一属性,最后是http://www.w3.org/TR/xquery-operators/#func-ends-允许带有单个项目的序列作为其第一个参数或者空序列但不是几个项目。

最可能的解释是您使用的是XPath 1.0处理器。 ends-with()函数需要XPath 2.0支持。

 //*[not(self::input)][@*[substring(., string-length(.) -8) = 'Copyright']] 

可以用string-length(.)进行小修正

现在,它可能会奏效。