【问题标题】:How can I match on an attribute that contains a certain string?如何匹配包含某个字符串的属性?
【发布时间】:2010-11-26 07:25:05
【问题描述】:

当属性包含多个单词时,我在按属性选择节点时遇到问题。例如:

<div class="atag btag" />

这是我的 xpath 表达式:

//*[@class='atag']

表达式适用于

&lt;div class="atag" /&gt;

但不是前面的例子。如何选择&lt;div&gt;

【问题讨论】:

  • 我认为值得指出的是,“atag btag”是一个属性,而不是两个。您正在尝试在 xpath 中进行子字符串匹配。
  • 是的,你是对的——这就是我想要的。
  • 这就是为什么你应该使用 CSS 选择器...div.atagdiv.btag。超级简单,不是字符串匹配,而且速度更快(并且在浏览器中得到更好的支持)。 XPath(针对 HTML)应该归结为它对...通过包含的文本查找元素和 DOM 导航有用。

标签: xpath


【解决方案1】:

EDIT:查看 bobince 的解决方案,它使用 contains 而不是 start-with,以及确保比较在完整令牌的级别(以免将“atag”模式作为另一个“标签”的一部分找到)。

"atag btag" 是类属性的奇数,但永远不会少,试试吧:

//*[starts-with(@class,"atag")]

【讨论】:

  • 如果你的 XPath 引擎支持starts-with 命令,你可以使用它,例如我记得JVM 6 不支持它
  • @mjv:CSS 类属性指定多个值是很常见的。 CSS就是这样完成的。
  • @mjv 您不能保证该名称会出现在类属性的开头。
  • @thuktun @skaffman。谢谢,伟大的cmets。我相应地“重定向”到 bobince 解决方案。
  • 不适用于与上述等效的
【解决方案2】:

mjv 的回答是一个好的开始,但如果 atag 不是列出的第一个类名,则会失败。

通常的方法是相当笨拙:

//*[contains(concat(' ', @class, ' '), ' atag ')]

只要类仅由空格分隔,而不是其他形式的空格,则此方法有效。几乎总是这样。如果它可能不是,你必须让它更笨重:

//*[contains(concat(' ', normalize-space(@class), ' '), ' atag ')]

(通过类似类名的空格分隔字符串进行选择是如此常见的情况,令人惊讶的是它没有特定的 XPath 函数,例如 CSS3 的 '[class~="atag"]'。)

【讨论】:

  • 呸,xpath 需要一些修复
  • @Redbeard supra123 的答案是有问题的,如果你不想选择像“atagnumbertwo”这样的 CSS 类,但我承认这可能不太可能(:
  • @crazyrails:您能接受这个答案作为正确答案吗?这将帮助未来的搜索者确定您问题所描述问题的正确解决方案。谢谢!
  • @cha0site:是的,他们可以,在 XPath 2.0 及以下版本中。这个答案是在 XPath 2.0 正式发布之前编写的。见stackoverflow.com/a/12165032/423105stackoverflow.com/a/12165195/423105
  • 不要像我一样,在这个例子中删除你正在寻找的类周围的空格;它们实际上很重要。否则,它可能看起来有效,但却达不到目的。
【解决方案3】:

这是一个查找 className 包含 atag 的 div 元素的示例:

//div[contains(@class, 'atag')]

下面是一个示例,它查找 className 包含 atagbtag 的 div 元素:

//div[contains(@class, 'atag') and contains(@class ,'btag')]

不过,它也会找到像 class="catag bobtag" 这样的部分匹配项。

如果您不想要部分匹配,请参阅下面 bobince 的回答。

【讨论】:

  • @Redbeard:这是一个字面上的答案,但通常不是类匹配解决方案的目标。特别是它会匹配&lt;div class="Patagonia Halbtagsarbeit"&gt;,它包含目标字符串但不是具有给定类的div。
  • 这适用于简单的场景 - 但要注意是否要在更广泛的上下文中使用此答案,而对您正在检查的属性值的控制较少或没有控制。 The correct answer is bobince's.
  • 对不起,这不匹配一个类,它匹配一个子字符串
  • 这显然是错误的,因为它还发现:
    它不应该这样做。
  • 问题是“包含某个字符串”而不是“匹配某个类”
【解决方案4】:

要添加到 bobince 的答案... 如果您使用的任何工具/库使用 Xpath 2.0,您也可以这样做:

//*[count(index-of(tokenize(@class, '\s+' ), $classname)) = 1]

count() 显然是需要的,因为 index-of() 返回它在字符串中匹配的每个索引的序列。

【讨论】:

  • 我想你的意思是不要把 $classname 变量放在引号之间?因为它是一个字符串。
  • 最后,一个正确的(JavasScript 兼容的)getElementsByClassName 实现......当然除了字符串文字'$classname'
  • 这太复杂了。有关正确的 XPath 2.0 答案,请参阅 @DanielHaley 的回复。
【解决方案5】:

有效的 2.0 XPath:

//*[tokenize(@class,'\s+')='atag']

或使用变量:

//*[tokenize(@class,'\s+')=$classname]

【讨论】:

  • 如果@class 有多个元素,这将如何工作?因为它将返回一个单词列表并将其与字符串进行比较失败,错误的基数
  • @AlexisWilke - 来自规范 (w3.org/TR/xpath20/#id-general-comparisons):一般比较是存在量化的比较,可以应用于任何长度的操作数序列。 它适用于每个 2.0 处理器我试过了。
  • 另请注意,在 XPath 3.1 中,这可以简化为 //*[tokenize(@class)=$classname]
  • 为了完整起见,如果您有幸使用了模式感知 XPath 处理器,并且如果 @class 具有列表值类型,那么您可以简单地编写 //*[@class=$classname]
【解决方案6】:

试试这个://*[contains(@class, 'atag')]

【讨论】:

  • 如果类名是grabatagonabag怎么办? (提示:它仍然会匹配。)
【解决方案7】:

你可以试试下面的

By.CssSelector("div.atag.btag")

【讨论】:

    【解决方案8】:

    请注意,如果您可以假设 您感兴趣的类名不是另一个可能的类名的子字符串,那么 bobince 的答案可能过于复杂。如果这是真的,您可以通过 contains 函数简单地使用子字符串匹配。以下将匹配其类中包含子字符串 'atag' 的任何元素:

    //*[contains(@class,'atag')]
    

    如果上述假设不成立,则子字符串匹配将匹配您不想要的元素。在这种情况下,您必须找到单词边界。通过使用空格分隔符来查找类名边界,bobince 的第二个答案找到了完全匹配:

    //*[contains(concat(' ', normalize-space(@class), ' '), ' atag ')]
    

    这将匹配 atag 而不是 matag

    【讨论】:

    • 这是我一直在寻找的解决方案。它清楚地在 class='hello test world' 中找到 'test' 并且与 'hello test-test world' 不匹配。因为我只使用 XPath 1.0 并且没有 RegEx,所以这是唯一可行的解​​决方案。
    【解决方案9】:

    对于包含公共 url 的链接,必须在变量中进行控制台。然后依次尝试。

    webelements allLinks=driver.findelements(By.xpath("//a[contains(@href,'http://122.11.38.214/dl/appdl/application/apk')]"));
    int linkCount=allLinks.length();
    for(int i=0; <linkCount;i++)
    {
        driver.findelement(allLinks[i]).click();
    }
    

    【讨论】:

      【解决方案10】:

      我来这里是为了寻找 Ranorex Studio 9.0.1 的解决方案。那里还没有 contains() 。相反,我们可以使用正则表达式:

      div[@class~'atag']
      

      【讨论】:

        猜你喜欢
        相关资源
        最近更新 更多
        热门标签