如何匹配包含某个字符串的属性?

Posted

技术标签:

【中文标题】如何匹配包含某个字符串的属性?【英文标题】: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 中进行子字符串匹配。 是的,你是对的——这就是我想要的。 相关:***.com/questions/8808921/… 和 ***.com/questions/1604471/… 这就是为什么你应该使用 CSS 选择器...div.atagdiv.btag。超级简单,不是字符串匹配,而且速度更快(并且在浏览器中得到更好的支持)。 XPath(针对 html)应该归结为它对...通过包含的文本查找元素和 DOM 导航有用。 【参考方案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 正式发布之前编写的。见***.com/a/12165032/423105 或***.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']

【讨论】:

以上是关于如何匹配包含某个字符串的属性?的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式 如何完成匹配某个字符串 但是不包含指定字符串

如何在Linux下查找文件内容包含某个特定字符串的文件

判断字符串中是不是包含某个字符串

C#如何判断字符串中是不是包含某个字符

数据库查询操作

vba如何判断字符串里面是包含某个字符?