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

Alp*_*Alp 7 java xpath selenium-webdriver

我有以下Xpath表达式:

//*[not(input)][ends-with(@*, 'Copyright')]
Run Code Online (Sandbox Code Playgroud)

我希望它能给我所有元素 - 输入除外 - 任何以"Copyright"结尾的属性值.

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

表达不是法律表达

但这些表达没有问题:

//*[not(input)][starts-with(@*, 'Copyright')]
//*[ends-with(@*, 'Copyright')]
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

Dim*_*hev 5

我有以下Xpath表达式:

//*[not(input)][ends-with(@*, 'Copyright')]
Run Code Online (Sandbox Code Playgroud)

我希望它能给我所有元素 - 输入除外 - 任何以"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']]
Run Code Online (Sandbox Code Playgroud)

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

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/*">
     <xsl:copy-of select=
     "//*[not(self::input)]
           [@*[substring(., string-length() -8)
              = 'Copyright'
              ]
          ]"/>
 </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

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

<html>
 <input/>
 <a x="Copyright not"/>
 <a y="This is a Copyright"/>
</html>
Run Code Online (Sandbox Code Playgroud)

产生了想要的正确结果:

<a y="This is a Copyright"/>
Run Code Online (Sandbox Code Playgroud)

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

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:x="http://www.w3.org/1999/xhtml"
 >
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/*">
     <xsl:copy-of select=
     "//*[not(self::x:input)]
           [@*[substring(., string-length() -8)
              = 'Copyright'
              ]
          ]"/>
 </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

应用于此XML文档时:

<html xmlns="http://www.w3.org/1999/xhtml">
 <input z="This is a Copyright"/>
 <a x="Copyright not"/>
 <a y="This is a Copyright"/>
</html>
Run Code Online (Sandbox Code Playgroud)

产生了想要的正确结果:

<a xmlns="http://www.w3.org/1999/xhtml" y="This is a Copyright"/>
Run Code Online (Sandbox Code Playgroud)