当属性包含多个单词时,我在按属性选择节点时遇到问题.例如:
<div class="atag btag" />
Run Code Online (Sandbox Code Playgroud)
这是我的xpath表达式:
//*[@class='atag']
表达式适用于
<div class="atag" />
但不是前一个例子.我该如何选择<div>?
小智 473
无论属性的位置如何,都将选择它们
//div[contains(@class, 'atag') and contains(@class ,'btag')]
Run Code Online (Sandbox Code Playgroud)
bob*_*nce 298
mjv的答案是一个良好的开端,但如果atag不是列出的第一个类名,则会失败.
通常的方法是相当笨拙:
//*[contains(concat(' ', @class, ' '), ' atag ')]
Run Code Online (Sandbox Code Playgroud)
只要类仅由空格分隔,而不是其他形式的空格,这就可以工作.几乎总是如此.如果它可能不是,你必须使它更加笨拙:
//*[contains(concat(' ', normalize-space(@class), ' '), ' atag ')]
Run Code Online (Sandbox Code Playgroud)
(通过类名称的空格分隔字符串进行选择是一种常见的情况,令人惊讶的是它没有特定的XPath函数,比如CSS3的'[class~ ="atag"]'.)
mjv*_*mjv 38
编辑:请参阅bobince的解决方案,该解决方案使用包含而不是启动,以及确保在完整令牌级别完成比较的技巧(以免'atag'模式被发现为另一个'标签'的一部分).
"atag btag"是类属性的奇数值,但从不如此,请尝试:
//*[starts-with(@class,"atag")]
Run Code Online (Sandbox Code Playgroud)
Dan*_*ley 30
一个有效的2.0 XPath:
//*[tokenize(@class,'\s+')='atag']
Run Code Online (Sandbox Code Playgroud)
或者使用变量:
//*[tokenize(@class,'\s+')=$classname]
Run Code Online (Sandbox Code Playgroud)
小智 21
请注意,如果您可以假设您感兴趣的类名不是另一个可能类名的子字符串,那么bobince的答案可能会过于复杂.如果是这样,您可以通过contains函数简单地使用子字符串匹配.以下内容将匹配其类包含子字符串'atag'的任何元素:
//*[contains(@class,'atag')]
Run Code Online (Sandbox Code Playgroud)
如果上述假设不成立,则子字符串匹配将匹配您不想要的元素.在这种情况下,您必须找到单词边界.通过使用空格分隔符来查找类名边界,bobince的第二个答案找到完全匹配:
//*[contains(concat(' ', normalize-space(@class), ' '), ' atag ')]
Run Code Online (Sandbox Code Playgroud)
这将匹配atag而不是matag.
添加到bobince的答案...如果您使用的任何工具/库使用Xpath 2.0,您也可以这样做:
//*[count(index-of(tokenize(@class, '\s+' ), $classname)) = 1]
Run Code Online (Sandbox Code Playgroud)
显然需要count()因为index-of()返回它在字符串中匹配的每个索引的序列.