如何使用 xpath 匹配包裹在 html 标记中的 link 文本?

How do I match link text that is wrapped in an html tag using xpath?

我有这个link:

<a href="/stores/non-consequatur-totam/products/search?term=yellow">
    Search all categories in 
    <span style="font-weight: bold;">non consequatur totam's</span> 
    store for “yellow”
</a>

我正在尝试使用 xpath 来匹配它,但我只能使用 contains 和 text() 来匹配 span 之前的部分。我用的是水豚

page.all(:xpath, "//a[contains(text(), 'Search all categories in')]").first
=> #<Capybara::Element tag="a" path="/html/body/div[2]/div[3]/div[2]/div[1]/p[2]/a[1]">
page.all(:xpath, "//a[contains(text(), 'store for')]").first
=> nil

如何匹配实际文本,就像 jQuery 那样?我需要忽略内部 html 标签。我真的很想也能匹配跨度中的部分。

认为您正在寻找的是一个元素的字符串值。元素节点的字符串值只是其所有后代文本节点的串联。

几乎(为了避免文本内容中与单引号或双引号无关的问题)使用表达式 string(//a) 您显示的 HTML 片段:

<a href="/stores/non-consequatur-totam/products/search?term=yellow">
    Search all categories in 
    <span style="font-weight: bold;">non consequatur totams</span> 
    store for yellow
</a>

产量

[EMPTY OUTPUT LINE]
Search all categories in
non consequatur totams
store for yellow
[EMPTY OUTPUT LINE]

这就是 a 元素中的所有文本。现在,要通过其文本内容匹配 a 元素,请在谓词中测试 string()

//a[normalize-space(string(.)) = 'Search all categories in non consequatur totams store for yellow']

再次应用于稍作修改的输入,这将 return link 元素。

normalize-space() 是必需的,因为文本包含换行符,而这些字符很难包含在 XPath 表达式中。


回复您的评论并再举一个例子:

I would really like to be able to use a single contains, assuming I had <a>a b <span>c</span d</div> I would like to look for a b c

我假设你的意思是搜索

<a>a b <span>c</span> d</a>

并寻找 a b c d?使用上面解释的方法,使用

//a[normalize-space(string(.)) = 'a b c d']